diff --git a/coverage/coverage.out b/coverage/coverage.out index d53037e..69342bf 100644 --- a/coverage/coverage.out +++ b/coverage/coverage.out @@ -40,61 +40,54 @@ github.com/echovault/echovault/internal/config/config.go:247.2,249.45 2 0 github.com/echovault/echovault/internal/config/config.go:249.45,251.3 1 0 github.com/echovault/echovault/internal/config/config.go:253.2,253.18 1 0 github.com/echovault/echovault/internal/config/default.go:8.29,38.2 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:46.60,47.34 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:47.34,49.3 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:52.61,53.34 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:53.34,55.3 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:58.67,59.34 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:59.34,61.3 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:64.63,65.34 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:65.34,67.3 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:70.77,71.34 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:71.34,73.3 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:76.80,83.39 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:83.40,83.41 0 0 -github.com/echovault/echovault/internal/aof/log/store.go:86.2,86.33 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:86.33,88.3 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:91.2,91.46 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:91.46,94.17 2 1 -github.com/echovault/echovault/internal/aof/log/store.go:94.17,96.4 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:97.3,98.17 2 1 -github.com/echovault/echovault/internal/aof/log/store.go:98.17,100.4 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:101.3,101.15 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:106.2,106.51 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:106.51,107.13 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:107.13,108.8 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:108.8,110.40 2 1 -github.com/echovault/echovault/internal/aof/log/store.go:110.40,113.11 3 1 -github.com/echovault/echovault/internal/aof/log/store.go:115.5,116.41 2 0 -github.com/echovault/echovault/internal/aof/log/store.go:121.2,121.19 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:124.55,126.21 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:126.21,128.3 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:130.2,135.47 4 1 -github.com/echovault/echovault/internal/aof/log/store.go:135.47,137.3 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:139.2,139.49 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:139.49,140.38 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:140.38,142.4 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:145.2,145.12 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:148.40,149.21 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:149.21,151.3 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:152.2,152.12 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:155.43,160.47 3 1 -github.com/echovault/echovault/internal/aof/log/store.go:160.47,162.3 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:164.2,165.6 2 1 -github.com/echovault/echovault/internal/aof/log/store.go:165.6,167.34 2 1 -github.com/echovault/echovault/internal/aof/log/store.go:167.34,169.4 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:170.3,170.13 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:170.13,172.9 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:174.3,175.17 2 1 -github.com/echovault/echovault/internal/aof/log/store.go:175.17,177.4 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:178.3,178.31 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:181.2,181.12 1 1 -github.com/echovault/echovault/internal/aof/log/store.go:184.44,187.45 3 0 -github.com/echovault/echovault/internal/aof/log/store.go:187.45,189.3 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:191.2,191.47 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:191.47,193.3 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:194.2,194.12 1 0 -github.com/echovault/echovault/internal/aof/log/store.go:197.41,201.2 3 1 +github.com/echovault/echovault/internal/aof/engine.go:50.56,51.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:51.30,53.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:56.57,57.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:57.30,59.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:62.59,63.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:63.30,65.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:68.58,69.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:69.30,71.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:74.59,75.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:75.30,77.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:80.82,81.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:81.30,83.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:86.89,87.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:87.30,89.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:92.73,93.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:93.30,95.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:98.82,99.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:99.30,101.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:104.78,105.30 1 1 +github.com/echovault/echovault/internal/aof/engine.go:105.30,107.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:110.69,118.29 1 1 +github.com/echovault/echovault/internal/aof/engine.go:118.30,118.31 0 0 +github.com/echovault/echovault/internal/aof/engine.go:119.30,119.31 0 0 +github.com/echovault/echovault/internal/aof/engine.go:120.57,120.71 1 0 +github.com/echovault/echovault/internal/aof/engine.go:121.63,121.64 0 0 +github.com/echovault/echovault/internal/aof/engine.go:122.44,122.45 0 0 +github.com/echovault/echovault/internal/aof/engine.go:127.2,127.33 1 1 +github.com/echovault/echovault/internal/aof/engine.go:127.33,129.3 1 1 +github.com/echovault/echovault/internal/aof/engine.go:132.2,139.16 2 1 +github.com/echovault/echovault/internal/aof/engine.go:139.16,141.3 1 0 +github.com/echovault/echovault/internal/aof/engine.go:142.2,152.16 3 1 +github.com/echovault/echovault/internal/aof/engine.go:152.16,154.3 1 0 +github.com/echovault/echovault/internal/aof/engine.go:155.2,159.12 2 1 +github.com/echovault/echovault/internal/aof/engine.go:159.12,160.7 1 1 +github.com/echovault/echovault/internal/aof/engine.go:160.7,162.54 2 1 +github.com/echovault/echovault/internal/aof/engine.go:162.54,164.5 1 0 +github.com/echovault/echovault/internal/aof/engine.go:168.2,168.20 1 1 +github.com/echovault/echovault/internal/aof/engine.go:171.52,173.2 1 1 +github.com/echovault/echovault/internal/aof/engine.go:175.42,183.62 5 1 +github.com/echovault/echovault/internal/aof/engine.go:183.62,185.3 1 0 +github.com/echovault/echovault/internal/aof/engine.go:188.2,188.54 1 1 +github.com/echovault/echovault/internal/aof/engine.go:188.54,190.3 1 0 +github.com/echovault/echovault/internal/aof/engine.go:192.2,192.12 1 1 +github.com/echovault/echovault/internal/aof/engine.go:195.39,196.55 1 1 +github.com/echovault/echovault/internal/aof/engine.go:196.55,198.3 1 0 +github.com/echovault/echovault/internal/aof/engine.go:199.2,199.53 1 1 +github.com/echovault/echovault/internal/aof/engine.go:199.53,201.3 1 0 +github.com/echovault/echovault/internal/aof/engine.go:202.2,202.12 1 1 github.com/echovault/echovault/internal/aof/preamble/store.go:45.62,46.36 1 1 github.com/echovault/echovault/internal/aof/preamble/store.go:46.36,48.3 1 1 github.com/echovault/echovault/internal/aof/preamble/store.go:51.71,52.36 1 0 @@ -150,54 +143,61 @@ github.com/echovault/echovault/internal/aof/preamble/store.go:185.43,187.4 1 1 github.com/echovault/echovault/internal/aof/preamble/store.go:189.2,189.35 1 1 github.com/echovault/echovault/internal/aof/preamble/store.go:189.35,191.3 1 1 github.com/echovault/echovault/internal/aof/preamble/store.go:192.2,192.14 1 1 -github.com/echovault/echovault/internal/aof/engine.go:50.56,51.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:51.30,53.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:56.57,57.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:57.30,59.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:62.59,63.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:63.30,65.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:68.58,69.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:69.30,71.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:74.59,75.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:75.30,77.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:80.82,81.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:81.30,83.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:86.89,87.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:87.30,89.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:92.73,93.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:93.30,95.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:98.82,99.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:99.30,101.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:104.78,105.30 1 1 -github.com/echovault/echovault/internal/aof/engine.go:105.30,107.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:110.69,118.29 1 1 -github.com/echovault/echovault/internal/aof/engine.go:118.30,118.31 0 0 -github.com/echovault/echovault/internal/aof/engine.go:119.30,119.31 0 0 -github.com/echovault/echovault/internal/aof/engine.go:120.57,120.71 1 0 -github.com/echovault/echovault/internal/aof/engine.go:121.63,121.64 0 0 -github.com/echovault/echovault/internal/aof/engine.go:122.44,122.45 0 0 -github.com/echovault/echovault/internal/aof/engine.go:127.2,127.33 1 1 -github.com/echovault/echovault/internal/aof/engine.go:127.33,129.3 1 1 -github.com/echovault/echovault/internal/aof/engine.go:132.2,139.16 2 1 -github.com/echovault/echovault/internal/aof/engine.go:139.16,141.3 1 0 -github.com/echovault/echovault/internal/aof/engine.go:142.2,152.16 3 1 -github.com/echovault/echovault/internal/aof/engine.go:152.16,154.3 1 0 -github.com/echovault/echovault/internal/aof/engine.go:155.2,159.12 2 1 -github.com/echovault/echovault/internal/aof/engine.go:159.12,160.7 1 1 -github.com/echovault/echovault/internal/aof/engine.go:160.7,162.54 2 1 -github.com/echovault/echovault/internal/aof/engine.go:162.54,164.5 1 0 -github.com/echovault/echovault/internal/aof/engine.go:168.2,168.20 1 1 -github.com/echovault/echovault/internal/aof/engine.go:171.52,173.2 1 1 -github.com/echovault/echovault/internal/aof/engine.go:175.42,183.62 5 1 -github.com/echovault/echovault/internal/aof/engine.go:183.62,185.3 1 0 -github.com/echovault/echovault/internal/aof/engine.go:188.2,188.54 1 1 -github.com/echovault/echovault/internal/aof/engine.go:188.54,190.3 1 0 -github.com/echovault/echovault/internal/aof/engine.go:192.2,192.12 1 1 -github.com/echovault/echovault/internal/aof/engine.go:195.39,196.55 1 1 -github.com/echovault/echovault/internal/aof/engine.go:196.55,198.3 1 0 -github.com/echovault/echovault/internal/aof/engine.go:199.2,199.53 1 1 -github.com/echovault/echovault/internal/aof/engine.go:199.53,201.3 1 0 -github.com/echovault/echovault/internal/aof/engine.go:202.2,202.12 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:46.60,47.34 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:47.34,49.3 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:52.61,53.34 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:53.34,55.3 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:58.67,59.34 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:59.34,61.3 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:64.63,65.34 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:65.34,67.3 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:70.77,71.34 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:71.34,73.3 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:76.80,83.39 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:83.40,83.41 0 0 +github.com/echovault/echovault/internal/aof/log/store.go:86.2,86.33 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:86.33,88.3 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:91.2,91.46 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:91.46,94.17 2 1 +github.com/echovault/echovault/internal/aof/log/store.go:94.17,96.4 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:97.3,98.17 2 1 +github.com/echovault/echovault/internal/aof/log/store.go:98.17,100.4 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:101.3,101.15 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:106.2,106.51 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:106.51,107.13 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:107.13,108.8 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:108.8,110.40 2 1 +github.com/echovault/echovault/internal/aof/log/store.go:110.40,113.11 3 1 +github.com/echovault/echovault/internal/aof/log/store.go:115.5,116.41 2 0 +github.com/echovault/echovault/internal/aof/log/store.go:121.2,121.19 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:124.55,126.21 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:126.21,128.3 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:130.2,135.47 4 1 +github.com/echovault/echovault/internal/aof/log/store.go:135.47,137.3 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:139.2,139.49 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:139.49,140.38 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:140.38,142.4 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:145.2,145.12 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:148.40,149.21 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:149.21,151.3 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:152.2,152.12 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:155.43,160.47 3 1 +github.com/echovault/echovault/internal/aof/log/store.go:160.47,162.3 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:164.2,165.6 2 1 +github.com/echovault/echovault/internal/aof/log/store.go:165.6,167.34 2 1 +github.com/echovault/echovault/internal/aof/log/store.go:167.34,169.4 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:170.3,170.13 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:170.13,172.9 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:174.3,175.17 2 1 +github.com/echovault/echovault/internal/aof/log/store.go:175.17,177.4 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:178.3,178.31 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:181.2,181.12 1 1 +github.com/echovault/echovault/internal/aof/log/store.go:184.44,187.45 3 0 +github.com/echovault/echovault/internal/aof/log/store.go:187.45,189.3 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:191.2,191.47 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:191.47,193.3 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:194.2,194.12 1 0 +github.com/echovault/echovault/internal/aof/log/store.go:197.41,201.2 3 1 github.com/echovault/echovault/internal/eviction/lfu.go:35.29,42.2 3 1 github.com/echovault/echovault/internal/eviction/lfu.go:44.34,46.2 1 1 github.com/echovault/echovault/internal/eviction/lfu.go:48.44,50.54 1 1 @@ -232,449 +232,444 @@ github.com/echovault/echovault/internal/eviction/lru.go:92.73,94.3 1 0 github.com/echovault/echovault/internal/eviction/lru.go:95.2,95.19 1 0 github.com/echovault/echovault/internal/eviction/lru.go:95.19,97.3 1 0 github.com/echovault/echovault/internal/eviction/lru.go:100.50,103.2 2 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:52.40,57.24 3 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:57.24,65.3 2 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:68.2,68.28 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:68.28,70.54 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:70.54,71.14 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:72.9,73.17 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:73.17,74.37 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:74.37,76.6 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:79.4,81.22 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:81.22,82.61 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:82.61,84.6 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:87.4,87.39 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:87.39,88.61 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:88.61,90.6 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:96.2,97.29 2 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:97.29,98.33 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:98.33,100.9 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:103.2,103.20 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:103.20,105.3 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:108.2,108.29 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:108.29,110.3 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:112.2,122.13 3 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:125.52,130.70 3 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:130.70,132.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:133.2,137.3 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:140.45,146.33 3 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:146.33,147.30 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:147.30,148.47 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:148.47,150.5 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:150.10,153.5 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:157.2,158.45 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:158.45,160.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:162.2,169.12 4 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:172.41,177.2 3 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:179.73,184.37 4 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:184.37,185.28 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:185.28,187.12 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:190.3,190.31 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:190.31,191.30 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:191.30,193.5 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:196.3,196.18 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:196.18,197.12 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:200.3,200.52 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:200.52,201.49 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:201.49,203.5 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:206.3,206.63 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:206.63,208.4 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:210.2,210.12 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:213.95,222.19 6 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:222.19,230.60 3 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:230.60,232.4 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:233.3,233.24 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:236.2,236.19 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:236.19,245.31 4 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:245.31,246.28 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:246.28,249.10 3 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:252.3,252.17 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:252.17,254.4 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:258.2,258.19 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:258.19,260.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:263.2,263.21 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:263.21,269.3 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:271.2,271.46 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:271.46,272.38 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:272.38,275.18 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:275.18,282.5 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:286.2,286.50 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:289.131,298.16 6 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:298.16,300.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:302.2,306.59 4 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:306.59,310.17 4 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:310.17,312.4 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:316.2,316.36 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:316.36,318.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:321.2,321.43 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:321.43,323.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:326.2,326.37 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:326.37,328.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:331.2,334.29 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:334.29,336.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:339.2,339.57 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:339.57,341.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:344.2,345.65 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:345.65,346.101 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:346.101,347.63 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:347.63,349.5 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:350.4,351.16 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:353.5,354.27 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:354.27,356.4 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:357.3,357.88 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:361.2,361.64 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:361.64,362.101 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:362.101,363.63 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:363.63,366.5 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:367.4,367.16 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:369.5,371.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:374.2,374.94 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:374.94,376.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:376.5,378.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:381.2,381.93 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:381.93,383.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:383.5,385.3 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:388.2,388.59 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:388.59,390.36 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:390.36,392.106 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:392.106,394.5 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:394.7,396.5 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:398.4,398.105 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:398.105,400.5 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:400.7,402.5 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:404.3,404.13 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:407.2,407.45 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:407.45,409.29 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:409.29,411.4 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:414.3,414.59 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:414.59,415.95 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:415.95,416.49 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:416.49,418.6 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:419.5,420.17 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:422.6,424.4 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:427.3,427.60 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:427.60,428.97 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:428.97,429.50 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:429.50,431.6 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:432.5,433.17 2 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:435.6,437.4 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:440.2,440.12 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:443.32,447.33 3 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:447.33,452.31 5 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:452.31,453.37 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:453.37,455.5 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:457.3,457.25 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:460.2,460.29 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:460.29,461.33 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:461.33,463.4 1 1 -github.com/echovault/echovault/internal/modules/acl/acl.go:467.29,469.2 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:471.31,473.2 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:475.30,477.2 1 0 -github.com/echovault/echovault/internal/modules/acl/acl.go:479.32,481.2 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:31.68,32.56 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:32.56,34.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:35.2,36.9 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:36.9,38.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:39.2,39.102 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:39.102,41.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:42.2,42.42 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:45.71,46.30 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:46.30,48.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:50.2,51.9 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:51.9,53.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:55.2,57.30 3 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:57.30,58.38 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:58.38,61.9 3 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:65.2,65.16 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:65.16,67.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:70.2,74.18 3 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:74.18,76.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:76.8,78.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:79.2,79.21 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:79.21,81.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:82.2,82.17 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:82.17,84.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:86.2,87.29 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:87.29,89.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:92.2,93.51 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:93.51,94.22 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:94.22,96.12 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:98.3,98.49 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:100.2,100.51 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:100.51,101.22 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:101.22,103.12 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:105.3,105.49 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:109.2,110.48 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:110.48,111.21 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:111.21,113.12 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:115.3,115.47 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:117.2,117.48 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:117.48,118.21 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:118.21,120.12 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:122.3,122.47 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:126.2,127.79 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:127.79,128.37 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:128.37,130.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:132.2,133.30 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:133.30,134.10 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:135.100,137.53 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:138.53,140.52 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:141.52,143.52 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:148.2,150.54 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:150.54,152.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:153.2,153.54 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:153.54,155.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:157.2,159.25 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:162.67,163.29 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:163.29,165.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:167.2,171.35 3 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:171.35,172.36 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:172.36,173.48 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:173.48,175.5 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:176.4,176.12 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:178.3,178.50 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:178.50,179.51 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:179.51,182.5 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:186.2,186.30 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:186.30,189.34 3 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:189.34,192.4 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:193.3,194.28 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:194.28,196.24 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:196.24,198.5 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:200.3,200.26 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:203.2,203.30 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:203.30,205.46 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:205.46,206.54 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:206.54,208.38 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:208.38,210.30 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:210.30,212.7 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:214.5,214.28 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:219.2,219.85 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:222.69,224.9 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:224.9,226.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:227.2,228.33 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:228.33,230.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:231.2,232.25 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:235.71,237.9 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:237.9,239.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:240.2,240.56 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:240.56,242.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:243.2,243.42 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:246.71,247.29 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:247.29,249.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:250.2,251.9 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:251.9,253.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:254.2,254.75 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:254.75,256.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:257.2,257.42 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:260.70,262.9 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:262.9,264.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:265.2,266.74 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:269.68,270.29 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:270.29,272.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:273.2,274.9 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:274.9,276.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:277.2,279.33 3 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:279.33,282.19 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:282.19,284.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:284.9,286.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:288.3,288.22 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:288.22,290.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:292.3,292.18 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:292.18,294.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:296.3,296.43 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:296.43,297.61 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:297.61,299.5 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:300.4,300.58 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:300.58,302.5 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:305.3,305.52 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:305.52,306.23 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:306.23,308.13 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:310.4,310.39 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:313.3,313.52 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:313.52,314.23 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:314.23,316.13 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:318.4,318.39 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:321.3,321.49 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:321.49,322.22 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:322.22,324.13 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:326.4,326.37 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:329.3,329.49 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:329.49,330.22 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:330.22,332.13 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:334.4,334.37 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:337.3,337.45 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:337.45,338.52 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:338.52,340.13 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:342.4,342.41 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:345.3,345.45 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:345.45,346.52 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:346.52,348.5 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:351.3,351.55 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:351.55,353.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:355.3,355.55 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:355.55,357.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:358.3,358.54 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:361.2,362.25 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:365.68,366.30 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:366.30,368.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:370.2,371.9 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:371.9,373.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:375.2,379.16 4 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:379.16,381.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:383.2,383.15 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:383.15,384.35 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:384.35,386.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:389.2,393.20 3 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:393.20,394.59 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:394.59,396.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:399.2,399.37 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:399.37,400.59 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:400.59,402.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:406.2,406.29 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:406.29,410.31 3 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:410.31,411.35 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:411.35,414.54 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:414.54,416.6 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:416.11,419.6 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:420.5,420.10 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:424.3,424.17 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:424.17,426.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:429.2,429.42 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:432.68,433.29 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:433.29,435.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:437.2,438.9 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:438.9,440.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:442.2,446.16 4 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:446.16,448.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:450.2,450.15 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:450.15,451.35 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:451.35,453.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:456.2,458.20 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:458.20,461.17 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:461.17,463.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:464.3,465.17 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:465.17,467.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:470.2,470.37 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:470.37,473.17 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:473.17,475.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:476.3,477.17 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:477.17,479.4 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:482.2,483.16 2 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:483.16,485.3 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:487.2,487.42 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:490.36,500.84 1 1 -github.com/echovault/echovault/internal/modules/acl/commands.go:500.84,506.5 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:515.84,521.5 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:530.86,536.7 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:545.86,551.7 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:560.86,566.7 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:575.86,581.7 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:591.86,597.7 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:606.86,612.7 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:621.86,627.7 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:639.86,645.7 1 0 -github.com/echovault/echovault/internal/modules/acl/commands.go:654.86,660.7 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:53.31,55.39 2 1 -github.com/echovault/echovault/internal/modules/acl/user.go:55.39,57.3 1 1 -github.com/echovault/echovault/internal/modules/acl/user.go:58.2,59.51 2 1 -github.com/echovault/echovault/internal/modules/acl/user.go:59.51,61.3 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:63.2,64.37 2 1 -github.com/echovault/echovault/internal/modules/acl/user.go:64.37,66.3 1 1 -github.com/echovault/echovault/internal/modules/acl/user.go:67.2,68.49 2 1 -github.com/echovault/echovault/internal/modules/acl/user.go:68.49,70.3 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:72.2,73.53 2 1 -github.com/echovault/echovault/internal/modules/acl/user.go:73.53,75.3 1 1 -github.com/echovault/echovault/internal/modules/acl/user.go:76.2,77.54 2 1 -github.com/echovault/echovault/internal/modules/acl/user.go:77.54,79.3 1 1 -github.com/echovault/echovault/internal/modules/acl/user.go:81.2,82.43 2 1 -github.com/echovault/echovault/internal/modules/acl/user.go:82.43,84.3 1 1 -github.com/echovault/echovault/internal/modules/acl/user.go:85.2,86.55 2 1 -github.com/echovault/echovault/internal/modules/acl/user.go:86.55,88.3 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:91.79,93.32 2 1 -github.com/echovault/echovault/internal/modules/acl/user.go:93.32,94.24 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:94.24,96.12 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:98.3,98.25 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:100.2,100.33 1 1 -github.com/echovault/echovault/internal/modules/acl/user.go:100.33,101.17 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:101.17,104.4 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:105.3,105.25 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:107.2,107.8 1 1 -github.com/echovault/echovault/internal/modules/acl/user.go:110.50,111.26 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:111.26,113.35 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:113.35,115.4 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:116.3,116.36 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:116.36,118.4 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:120.3,120.37 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:120.37,126.12 3 0 -github.com/echovault/echovault/internal/modules/acl/user.go:128.3,128.20 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:128.20,129.84 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:129.84,130.65 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:130.65,132.6 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:133.5,133.45 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:135.4,135.12 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:137.3,137.20 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:137.20,138.84 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:138.84,139.68 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:139.68,141.6 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:142.5,142.45 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:144.4,144.12 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:147.3,147.43 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:147.43,150.12 3 0 -github.com/echovault/echovault/internal/modules/acl/user.go:152.3,152.46 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:152.46,154.12 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:156.3,156.36 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:156.36,157.21 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:157.21,159.13 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:161.4,161.21 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:161.21,163.13 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:167.3,167.40 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:167.40,171.12 4 0 -github.com/echovault/echovault/internal/modules/acl/user.go:173.3,173.93 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:173.93,178.12 5 0 -github.com/echovault/echovault/internal/modules/acl/user.go:180.3,180.57 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:180.57,183.12 3 0 -github.com/echovault/echovault/internal/modules/acl/user.go:185.3,185.57 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:185.57,188.12 3 0 -github.com/echovault/echovault/internal/modules/acl/user.go:191.3,191.44 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:191.44,193.12 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:195.3,195.36 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:195.36,196.21 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:196.21,198.13 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:200.4,200.21 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:200.21,202.13 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:206.3,206.44 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:206.44,209.12 3 0 -github.com/echovault/echovault/internal/modules/acl/user.go:211.3,211.66 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:211.66,212.21 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:212.21,214.13 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:216.4,216.21 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:216.21,218.13 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:224.2,224.26 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:224.26,225.39 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:225.39,228.4 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:231.2,231.26 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:231.26,233.42 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:233.42,236.4 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:238.3,238.43 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:238.43,243.4 4 0 -github.com/echovault/echovault/internal/modules/acl/user.go:245.3,245.42 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:245.42,249.4 3 0 -github.com/echovault/echovault/internal/modules/acl/user.go:251.3,251.46 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:251.46,254.4 2 0 -github.com/echovault/echovault/internal/modules/acl/user.go:256.2,256.12 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:259.36,273.2 13 0 -github.com/echovault/echovault/internal/modules/acl/user.go:275.38,288.2 12 0 -github.com/echovault/echovault/internal/modules/acl/user.go:290.40,305.2 1 1 -github.com/echovault/echovault/internal/modules/acl/user.go:307.46,308.24 1 1 -github.com/echovault/echovault/internal/modules/acl/user.go:308.24,310.3 1 0 -github.com/echovault/echovault/internal/modules/acl/user.go:311.2,311.26 1 1 github.com/echovault/echovault/internal/modules/connection/commands.go:24.68,25.29 1 1 github.com/echovault/echovault/internal/modules/connection/commands.go:26.10,27.54 1 1 github.com/echovault/echovault/internal/modules/connection/commands.go:28.9,29.34 1 1 github.com/echovault/echovault/internal/modules/connection/commands.go:30.9,31.94 1 1 github.com/echovault/echovault/internal/modules/connection/commands.go:35.36,45.84 1 1 github.com/echovault/echovault/internal/modules/connection/commands.go:45.84,51.5 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:28.68,30.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:30.16,32.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:34.2,38.36 4 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:38.36,40.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:42.2,42.49 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:42.49,44.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:46.2,46.16 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:46.16,47.17 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:47.17,49.4 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:50.3,50.95 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:50.95,52.4 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:53.3,53.59 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:56.2,57.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:57.9,59.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:61.2,62.36 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:62.36,63.53 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:63.53,64.26 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:64.26,67.5 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:68.4,68.12 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:70.3,71.13 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:73.2,73.91 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:73.91,75.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:77.2,77.51 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:80.68,82.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:82.16,84.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:86.2,90.16 4 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:90.16,92.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:94.2,95.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:95.9,97.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:99.2,102.31 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:102.31,104.19 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:104.19,106.12 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:108.3,108.34 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:108.34,110.12 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:112.3,112.31 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:112.31,114.12 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:116.3,116.35 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:116.35,119.12 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:121.3,121.32 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:124.2,124.25 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:127.71,129.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:129.16,131.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:133.2,137.16 4 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:137.16,139.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:141.2,142.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:142.9,144.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:146.2,149.31 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:149.31,151.19 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:151.19,153.12 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:155.3,155.34 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:155.34,157.12 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:159.3,159.35 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:159.35,162.12 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:164.3,164.31 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:164.31,166.12 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:168.3,168.18 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:171.2,171.25 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:174.69,176.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:176.16,178.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:180.2,183.16 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:183.16,185.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:187.2,188.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:188.9,190.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:192.2,193.27 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:193.27,194.32 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:194.32,196.12 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:198.3,198.33 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:198.33,201.12 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:203.3,203.29 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:203.29,205.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:208.2,208.25 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:211.74,213.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:213.16,215.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:217.2,221.30 4 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:221.30,223.17 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:223.17,225.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:226.3,226.13 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:226.13,228.4 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:229.3,229.12 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:232.2,233.30 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:233.30,234.57 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:234.57,236.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:236.9,238.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:241.2,241.16 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:241.16,243.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:245.2,246.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:246.9,248.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:251.2,251.24 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:251.24,253.17 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:253.17,255.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:256.3,256.34 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:256.34,258.18 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:258.18,259.36 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:259.36,261.14 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:263.5,263.37 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:263.37,266.14 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:268.5,268.33 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:268.33,270.14 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:274.3,274.26 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:278.2,279.29 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:279.29,281.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:284.2,286.46 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:286.46,290.16 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:290.16,291.59 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:291.59,293.5 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:297.2,298.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:298.16,300.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:301.2,301.38 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:301.38,303.17 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:303.17,304.41 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:304.41,306.13 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:308.4,308.42 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:308.42,311.13 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:313.4,313.38 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:313.38,315.13 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:320.2,320.25 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:323.68,325.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:325.16,327.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:329.2,332.16 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:332.16,334.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:336.2,337.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:337.9,339.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:341.2,341.55 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:344.69,346.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:346.16,348.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:350.2,353.16 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:353.16,355.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:357.2,358.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:358.9,360.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:362.2,363.29 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:363.29,365.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:367.2,367.25 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:370.71,372.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:372.16,374.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:376.2,383.58 6 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:383.58,385.17 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:385.17,387.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:388.3,388.21 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:389.8,391.17 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:391.17,393.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:394.3,394.19 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:397.2,397.16 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:397.16,399.59 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:399.59,401.93 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:401.93,403.5 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:404.4,404.96 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:405.9,407.93 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:407.93,409.5 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:410.4,410.60 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:414.2,415.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:415.9,417.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:419.2,419.24 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:419.24,421.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:423.2,423.28 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:424.10,425.69 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:426.11,428.59 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:428.59,430.4 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:430.9,432.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:433.15,435.59 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:435.59,437.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:437.9,439.4 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:442.2,442.91 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:442.91,444.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:446.2,446.40 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:446.40,448.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:450.2,451.47 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:454.71,456.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:456.16,458.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:460.2,463.16 3 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:463.16,465.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:467.2,468.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:468.9,470.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:472.2,473.33 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:473.33,475.34 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:475.34,477.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:478.3,478.35 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:478.35,481.4 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:482.3,482.31 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:482.31,484.4 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:487.2,487.25 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:490.71,492.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:492.16,494.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:496.2,500.16 4 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:500.16,502.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:504.2,505.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:505.9,507.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:509.2,509.24 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:509.24,511.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:513.2,513.30 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:516.68,518.16 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:518.16,520.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:522.2,526.16 4 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:526.16,528.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:530.2,531.9 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:531.9,533.3 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:535.2,537.31 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:537.31,538.25 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:538.25,541.4 2 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:544.2,544.91 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:544.91,546.3 1 0 +github.com/echovault/echovault/internal/modules/hash/commands.go:548.2,548.51 1 1 +github.com/echovault/echovault/internal/modules/hash/commands.go:551.36,675.2 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:23.74,24.18 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:24.18,26.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:27.2,31.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:34.76,35.18 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:35.18,37.3 1 0 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:38.2,42.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:45.74,46.18 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:46.18,48.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:49.2,53.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:56.77,57.18 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:57.18,59.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:60.2,64.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:67.75,68.19 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:68.19,70.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:71.2,75.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:78.80,79.34 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:79.34,81.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:82.2,82.19 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:82.19,88.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:89.2,93.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:96.74,97.19 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:97.19,99.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:100.2,104.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:107.75,108.19 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:108.19,110.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:111.2,115.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:118.77,119.19 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:119.19,121.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:122.2,126.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:129.77,130.19 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:130.19,132.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:133.2,137.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:140.77,141.19 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:141.19,143.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:144.2,148.8 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:151.74,152.18 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:152.18,154.3 1 1 +github.com/echovault/echovault/internal/modules/hash/key_funcs.go:155.2,159.8 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:27.68,29.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:29.16,31.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:33.2,36.16 3 1 +github.com/echovault/echovault/internal/modules/list/commands.go:36.16,39.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:41.2,41.90 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:41.90,43.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:45.2,45.57 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:48.70,50.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:50.16,52.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:54.2,58.9 4 1 +github.com/echovault/echovault/internal/modules/list/commands.go:58.9,60.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:62.2,62.16 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:62.16,64.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:66.2,67.9 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:67.9,69.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:71.2,71.40 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:71.40,73.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:75.2,75.57 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:78.70,80.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:80.16,82.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:84.2,89.24 5 1 +github.com/echovault/echovault/internal/modules/list/commands.go:89.24,91.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:93.2,93.16 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:93.16,95.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:97.2,98.9 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:98.9,100.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:103.2,103.40 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:103.40,105.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:108.2,108.51 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:108.51,110.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:112.2,115.15 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:115.15,117.43 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:117.43,120.4 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:121.3,121.20 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:125.2,125.18 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:125.18,127.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:132.2,136.17 4 1 +github.com/echovault/echovault/internal/modules/list/commands.go:136.17,138.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:140.2,140.13 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:140.13,143.18 3 1 +github.com/echovault/echovault/internal/modules/list/commands.go:143.18,145.4 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:145.9,147.4 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:150.2,150.19 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:153.68,155.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:155.16,157.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:159.2,163.9 4 1 +github.com/echovault/echovault/internal/modules/list/commands.go:163.9,165.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:167.2,167.16 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:167.16,169.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:171.2,172.9 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:172.9,174.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:176.2,176.40 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:176.40,178.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:180.2,181.91 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:181.91,183.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:185.2,185.42 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:188.69,190.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:190.16,192.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:194.2,199.24 5 1 +github.com/echovault/echovault/internal/modules/list/commands.go:199.24,201.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:203.2,203.30 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:203.30,205.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:207.2,207.16 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:207.16,209.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:211.2,212.9 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:212.9,214.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:216.2,216.40 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:216.40,218.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:220.2,220.34 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:220.34,221.100 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:221.100,223.4 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:224.3,224.43 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:227.2,227.102 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:227.102,229.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:230.2,230.42 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:233.68,235.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:235.16,237.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:239.2,244.9 5 1 +github.com/echovault/echovault/internal/modules/list/commands.go:244.9,246.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:248.2,250.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:250.16,252.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:254.2,255.9 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:255.9,257.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:259.2,259.9 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:260.10,260.10 0 0 +github.com/echovault/echovault/internal/modules/list/commands.go:262.17,264.34 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:264.34,265.26 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:265.26,266.10 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:268.4,268.43 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:268.43,271.5 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:273.17,275.39 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:275.39,276.26 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:276.26,277.10 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:279.4,279.43 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:279.43,282.5 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:286.2,286.61 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:286.61,288.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:290.2,290.91 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:290.91,292.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:294.2,294.42 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:297.69,299.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:299.16,301.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:303.2,308.116 5 1 +github.com/echovault/echovault/internal/modules/list/commands.go:308.116,310.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:312.2,312.51 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:312.51,314.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:316.2,320.33 4 1 +github.com/echovault/echovault/internal/modules/list/commands.go:320.33,322.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:324.2,324.19 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:325.14,328.38 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:328.38,329.26 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:329.26,331.6 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:333.5,333.50 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:336.15,339.38 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:339.38,340.26 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:340.26,342.6 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:344.5,344.66 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:349.2,349.16 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:349.16,351.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:353.2,353.42 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:356.69,358.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:358.16,360.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:362.2,364.42 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:364.42,366.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:368.2,371.16 3 1 +github.com/echovault/echovault/internal/modules/list/commands.go:371.16,372.45 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:373.17,374.64 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:375.11,376.104 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:376.104,378.5 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:382.2,384.9 3 1 +github.com/echovault/echovault/internal/modules/list/commands.go:384.9,386.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:388.2,388.109 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:388.109,390.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:392.2,392.66 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:395.69,397.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:397.16,399.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:401.2,406.42 4 1 +github.com/echovault/echovault/internal/modules/list/commands.go:406.42,408.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:410.2,410.16 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:410.16,411.45 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:412.17,413.64 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:414.11,415.104 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:415.104,417.5 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:421.2,423.9 3 1 +github.com/echovault/echovault/internal/modules/list/commands.go:423.9,425.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:427.2,427.109 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:427.109,429.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:430.2,430.66 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:433.67,435.16 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:435.16,437.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:439.2,442.16 3 1 +github.com/echovault/echovault/internal/modules/list/commands.go:442.16,444.3 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:446.2,447.9 2 1 +github.com/echovault/echovault/internal/modules/list/commands.go:447.9,449.3 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:451.2,451.44 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:452.10,453.96 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:453.96,455.4 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:456.3,456.54 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:457.14,458.106 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:458.106,460.4 1 0 +github.com/echovault/echovault/internal/modules/list/commands.go:461.3,461.64 1 1 +github.com/echovault/echovault/internal/modules/list/commands.go:465.36,588.2 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:23.75,24.18 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:24.18,26.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:27.2,31.8 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:34.73,35.19 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:35.19,37.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:38.2,42.8 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:45.74,46.19 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:46.19,48.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:49.2,53.8 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:56.76,57.19 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:57.19,59.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:60.2,64.8 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:67.76,68.19 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:68.19,70.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:71.2,75.8 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:78.74,79.19 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:79.19,81.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:82.2,86.8 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:89.75,90.19 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:90.19,92.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:93.2,97.8 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:100.74,101.19 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:101.19,103.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:104.2,108.8 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:111.75,112.18 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:112.18,114.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:115.2,119.8 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:122.75,123.19 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:123.19,125.3 1 1 +github.com/echovault/echovault/internal/modules/list/key_funcs.go:126.2,130.8 1 1 github.com/echovault/echovault/internal/modules/generic/commands.go:33.67,35.16 2 1 github.com/echovault/echovault/internal/modules/generic/commands.go:35.16,37.3 1 0 github.com/echovault/echovault/internal/modules/generic/commands.go:39.2,46.16 7 1 @@ -885,198 +880,6 @@ github.com/echovault/echovault/internal/modules/generic/utils.go:107.3,109.17 3 github.com/echovault/echovault/internal/modules/generic/utils.go:109.17,111.4 1 1 github.com/echovault/echovault/internal/modules/generic/utils.go:112.3,113.55 2 1 github.com/echovault/echovault/internal/modules/generic/utils.go:115.10,116.96 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:27.68,29.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:29.16,31.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:33.2,36.16 3 1 -github.com/echovault/echovault/internal/modules/list/commands.go:36.16,39.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:41.2,41.90 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:41.90,43.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:45.2,45.57 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:48.70,50.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:50.16,52.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:54.2,58.9 4 1 -github.com/echovault/echovault/internal/modules/list/commands.go:58.9,60.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:62.2,62.16 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:62.16,64.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:66.2,67.9 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:67.9,69.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:71.2,71.40 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:71.40,73.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:75.2,75.57 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:78.70,80.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:80.16,82.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:84.2,89.24 5 1 -github.com/echovault/echovault/internal/modules/list/commands.go:89.24,91.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:93.2,93.16 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:93.16,95.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:97.2,98.9 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:98.9,100.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:103.2,103.40 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:103.40,105.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:108.2,108.51 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:108.51,110.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:112.2,115.15 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:115.15,117.43 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:117.43,120.4 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:121.3,121.20 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:125.2,125.18 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:125.18,127.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:132.2,136.17 4 1 -github.com/echovault/echovault/internal/modules/list/commands.go:136.17,138.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:140.2,140.13 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:140.13,143.18 3 1 -github.com/echovault/echovault/internal/modules/list/commands.go:143.18,145.4 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:145.9,147.4 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:150.2,150.19 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:153.68,155.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:155.16,157.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:159.2,163.9 4 1 -github.com/echovault/echovault/internal/modules/list/commands.go:163.9,165.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:167.2,167.16 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:167.16,169.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:171.2,172.9 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:172.9,174.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:176.2,176.40 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:176.40,178.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:180.2,181.91 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:181.91,183.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:185.2,185.42 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:188.69,190.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:190.16,192.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:194.2,199.24 5 1 -github.com/echovault/echovault/internal/modules/list/commands.go:199.24,201.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:203.2,203.30 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:203.30,205.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:207.2,207.16 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:207.16,209.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:211.2,212.9 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:212.9,214.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:216.2,216.40 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:216.40,218.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:220.2,220.34 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:220.34,221.100 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:221.100,223.4 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:224.3,224.43 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:227.2,227.102 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:227.102,229.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:230.2,230.42 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:233.68,235.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:235.16,237.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:239.2,244.9 5 1 -github.com/echovault/echovault/internal/modules/list/commands.go:244.9,246.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:248.2,250.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:250.16,252.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:254.2,255.9 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:255.9,257.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:259.2,259.9 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:260.10,260.10 0 0 -github.com/echovault/echovault/internal/modules/list/commands.go:262.17,264.34 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:264.34,265.26 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:265.26,266.10 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:268.4,268.43 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:268.43,271.5 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:273.17,275.39 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:275.39,276.26 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:276.26,277.10 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:279.4,279.43 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:279.43,282.5 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:286.2,286.61 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:286.61,288.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:290.2,290.91 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:290.91,292.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:294.2,294.42 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:297.69,299.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:299.16,301.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:303.2,308.116 5 1 -github.com/echovault/echovault/internal/modules/list/commands.go:308.116,310.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:312.2,312.51 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:312.51,314.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:316.2,320.33 4 1 -github.com/echovault/echovault/internal/modules/list/commands.go:320.33,322.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:324.2,324.19 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:325.14,328.38 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:328.38,329.26 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:329.26,331.6 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:333.5,333.50 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:336.15,339.38 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:339.38,340.26 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:340.26,342.6 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:344.5,344.66 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:349.2,349.16 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:349.16,351.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:353.2,353.42 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:356.69,358.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:358.16,360.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:362.2,364.42 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:364.42,366.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:368.2,371.16 3 1 -github.com/echovault/echovault/internal/modules/list/commands.go:371.16,372.45 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:373.17,374.64 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:375.11,376.104 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:376.104,378.5 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:382.2,384.9 3 1 -github.com/echovault/echovault/internal/modules/list/commands.go:384.9,386.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:388.2,388.109 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:388.109,390.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:392.2,392.66 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:395.69,397.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:397.16,399.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:401.2,406.42 4 1 -github.com/echovault/echovault/internal/modules/list/commands.go:406.42,408.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:410.2,410.16 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:410.16,411.45 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:412.17,413.64 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:414.11,415.104 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:415.104,417.5 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:421.2,423.9 3 1 -github.com/echovault/echovault/internal/modules/list/commands.go:423.9,425.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:427.2,427.109 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:427.109,429.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:430.2,430.66 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:433.67,435.16 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:435.16,437.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:439.2,442.16 3 1 -github.com/echovault/echovault/internal/modules/list/commands.go:442.16,444.3 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:446.2,447.9 2 1 -github.com/echovault/echovault/internal/modules/list/commands.go:447.9,449.3 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:451.2,451.44 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:452.10,453.96 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:453.96,455.4 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:456.3,456.54 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:457.14,458.106 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:458.106,460.4 1 0 -github.com/echovault/echovault/internal/modules/list/commands.go:461.3,461.64 1 1 -github.com/echovault/echovault/internal/modules/list/commands.go:465.36,588.2 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:23.75,24.18 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:24.18,26.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:27.2,31.8 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:34.73,35.19 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:35.19,37.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:38.2,42.8 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:45.74,46.19 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:46.19,48.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:49.2,53.8 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:56.76,57.19 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:57.19,59.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:60.2,64.8 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:67.76,68.19 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:68.19,70.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:71.2,75.8 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:78.74,79.19 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:79.19,81.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:82.2,86.8 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:89.75,90.19 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:90.19,92.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:93.2,97.8 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:100.74,101.19 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:101.19,103.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:104.2,108.8 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:111.75,112.18 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:112.18,114.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:115.2,119.8 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:122.75,123.19 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:123.19,125.3 1 1 -github.com/echovault/echovault/internal/modules/list/key_funcs.go:126.2,130.8 1 1 github.com/echovault/echovault/internal/snapshot/snapshot.go:55.56,56.30 1 1 github.com/echovault/echovault/internal/snapshot/snapshot.go:56.30,58.3 1 1 github.com/echovault/echovault/internal/snapshot/snapshot.go:61.59,62.30 1 1 @@ -1179,246 +982,6 @@ github.com/echovault/echovault/internal/snapshot/snapshot.go:354.94,356.3 1 1 github.com/echovault/echovault/internal/snapshot/snapshot.go:358.2,360.12 2 1 github.com/echovault/echovault/internal/snapshot/snapshot.go:363.46,365.2 1 0 github.com/echovault/echovault/internal/snapshot/snapshot.go:367.42,369.2 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:28.68,30.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:30.16,32.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:34.2,38.36 4 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:38.36,40.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:42.2,42.49 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:42.49,44.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:46.2,46.16 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:46.16,47.17 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:47.17,49.4 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:50.3,50.95 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:50.95,52.4 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:53.3,53.59 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:56.2,57.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:57.9,59.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:61.2,62.36 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:62.36,63.53 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:63.53,64.26 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:64.26,67.5 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:68.4,68.12 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:70.3,71.13 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:73.2,73.91 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:73.91,75.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:77.2,77.51 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:80.68,82.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:82.16,84.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:86.2,90.16 4 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:90.16,92.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:94.2,95.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:95.9,97.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:99.2,102.31 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:102.31,104.19 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:104.19,106.12 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:108.3,108.34 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:108.34,110.12 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:112.3,112.31 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:112.31,114.12 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:116.3,116.35 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:116.35,119.12 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:121.3,121.32 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:124.2,124.25 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:127.71,129.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:129.16,131.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:133.2,137.16 4 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:137.16,139.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:141.2,142.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:142.9,144.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:146.2,149.31 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:149.31,151.19 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:151.19,153.12 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:155.3,155.34 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:155.34,157.12 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:159.3,159.35 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:159.35,162.12 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:164.3,164.31 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:164.31,166.12 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:168.3,168.18 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:171.2,171.25 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:174.69,176.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:176.16,178.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:180.2,183.16 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:183.16,185.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:187.2,188.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:188.9,190.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:192.2,193.27 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:193.27,194.32 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:194.32,196.12 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:198.3,198.33 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:198.33,201.12 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:203.3,203.29 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:203.29,205.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:208.2,208.25 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:211.74,213.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:213.16,215.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:217.2,221.30 4 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:221.30,223.17 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:223.17,225.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:226.3,226.13 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:226.13,228.4 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:229.3,229.12 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:232.2,233.30 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:233.30,234.57 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:234.57,236.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:236.9,238.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:241.2,241.16 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:241.16,243.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:245.2,246.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:246.9,248.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:251.2,251.24 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:251.24,253.17 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:253.17,255.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:256.3,256.34 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:256.34,258.18 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:258.18,259.36 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:259.36,261.14 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:263.5,263.37 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:263.37,266.14 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:268.5,268.33 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:268.33,270.14 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:274.3,274.26 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:278.2,279.29 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:279.29,281.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:284.2,286.46 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:286.46,290.16 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:290.16,291.59 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:291.59,293.5 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:297.2,298.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:298.16,300.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:301.2,301.38 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:301.38,303.17 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:303.17,304.41 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:304.41,306.13 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:308.4,308.42 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:308.42,311.13 3 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:313.4,313.38 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:313.38,315.13 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:320.2,320.25 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:323.68,325.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:325.16,327.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:329.2,332.16 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:332.16,334.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:336.2,337.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:337.9,339.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:341.2,341.55 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:344.69,346.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:346.16,348.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:350.2,353.16 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:353.16,355.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:357.2,358.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:358.9,360.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:362.2,363.29 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:363.29,365.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:367.2,367.25 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:370.71,372.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:372.16,374.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:376.2,383.58 6 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:383.58,385.17 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:385.17,387.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:388.3,388.21 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:389.8,391.17 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:391.17,393.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:394.3,394.19 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:397.2,397.16 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:397.16,399.59 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:399.59,401.93 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:401.93,403.5 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:404.4,404.96 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:405.9,407.93 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:407.93,409.5 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:410.4,410.60 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:414.2,415.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:415.9,417.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:419.2,419.24 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:419.24,421.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:423.2,423.28 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:424.10,425.69 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:426.11,428.59 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:428.59,430.4 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:430.9,432.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:433.15,435.59 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:435.59,437.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:437.9,439.4 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:442.2,442.91 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:442.91,444.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:446.2,446.40 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:446.40,448.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:450.2,451.47 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:454.71,456.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:456.16,458.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:460.2,463.16 3 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:463.16,465.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:467.2,468.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:468.9,470.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:472.2,473.33 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:473.33,475.34 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:475.34,477.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:478.3,478.35 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:478.35,481.4 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:482.3,482.31 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:482.31,484.4 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:487.2,487.25 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:490.71,492.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:492.16,494.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:496.2,500.16 4 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:500.16,502.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:504.2,505.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:505.9,507.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:509.2,509.24 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:509.24,511.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:513.2,513.30 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:516.68,518.16 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:518.16,520.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:522.2,526.16 4 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:526.16,528.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:530.2,531.9 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:531.9,533.3 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:535.2,537.31 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:537.31,538.25 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:538.25,541.4 2 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:544.2,544.91 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:544.91,546.3 1 0 -github.com/echovault/echovault/internal/modules/hash/commands.go:548.2,548.51 1 1 -github.com/echovault/echovault/internal/modules/hash/commands.go:551.36,675.2 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:23.74,24.18 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:24.18,26.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:27.2,31.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:34.76,35.18 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:35.18,37.3 1 0 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:38.2,42.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:45.74,46.18 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:46.18,48.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:49.2,53.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:56.77,57.18 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:57.18,59.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:60.2,64.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:67.75,68.19 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:68.19,70.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:71.2,75.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:78.80,79.34 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:79.34,81.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:82.2,82.19 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:82.19,88.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:89.2,93.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:96.74,97.19 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:97.19,99.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:100.2,104.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:107.75,108.19 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:108.19,110.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:111.2,115.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:118.77,119.19 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:119.19,121.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:122.2,126.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:129.77,130.19 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:130.19,132.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:133.2,137.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:140.77,141.19 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:141.19,143.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:144.2,148.8 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:151.74,152.18 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:152.18,154.3 1 1 -github.com/echovault/echovault/internal/modules/hash/key_funcs.go:155.2,159.8 1 1 github.com/echovault/echovault/internal/modules/set/commands.go:26.68,28.16 2 1 github.com/echovault/echovault/internal/modules/set/commands.go:28.16,30.3 1 0 github.com/echovault/echovault/internal/modules/set/commands.go:32.2,37.16 4 1 @@ -1711,6 +1274,99 @@ github.com/echovault/echovault/internal/modules/set/set.go:184.31,185.19 1 1 github.com/echovault/echovault/internal/modules/set/set.go:186.9,187.17 1 1 github.com/echovault/echovault/internal/modules/set/set.go:188.9,191.15 3 1 github.com/echovault/echovault/internal/modules/set/set.go:192.10,195.28 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:27.78,33.29 4 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:33.29,34.54 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:34.54,40.42 4 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:40.42,42.5 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:44.4,47.12 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:50.3,50.36 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:50.36,57.43 5 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:57.43,59.5 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:61.4,63.21 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:67.2,69.25 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:72.76,76.35 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:76.35,77.65 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:77.65,78.41 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:78.41,80.5 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:81.4,81.12 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:83.3,83.13 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:86.2,86.51 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:89.75,90.29 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:91.9,96.36 4 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:96.36,97.66 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:97.66,98.52 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:98.52,102.6 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:103.5,103.13 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:105.4,106.14 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:108.3,109.26 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:111.9,115.56 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:115.56,117.4 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:118.3,118.53 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:118.53,122.37 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:122.37,123.67 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:123.67,124.53 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:124.53,125.59 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:125.59,129.8 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:131.6,131.14 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:133.5,133.54 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:133.54,136.6 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:138.9,138.61 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:138.61,142.37 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:142.37,143.67 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:143.67,144.53 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:144.53,146.24 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:146.24,149.8 2 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:151.6,151.14 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:153.5,153.33 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:153.33,156.6 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:158.9,158.60 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:158.60,162.37 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:162.37,163.67 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:163.67,164.53 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:164.53,165.55 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:165.55,169.8 3 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:171.6,171.14 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:173.5,173.50 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:173.50,176.6 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:178.9,180.4 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:181.3,182.26 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:183.10,184.54 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:188.75,190.2 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:192.36,200.84 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:200.84,204.5 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:213.84,217.5 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:225.86,229.7 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:238.86,242.7 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:252.86,256.7 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:267.84,271.5 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:272.73,273.49 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:273.49,275.6 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:276.5,276.45 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:285.84,289.5 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:290.73,292.18 2 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:292.18,294.6 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:295.5,295.53 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:304.84,308.5 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:309.73,310.47 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:310.47,312.6 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:313.5,313.45 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:321.84,325.5 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:335.86,339.7 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:340.75,341.34 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:341.34,343.8 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:344.7,345.34 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:345.34,347.8 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:348.7,348.75 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:348.75,350.8 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:351.7,351.47 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:361.86,365.7 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:366.75,367.35 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:367.35,369.8 1 0 +github.com/echovault/echovault/internal/modules/admin/commands.go:370.7,371.47 2 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:380.86,384.7 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:385.75,388.38 3 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:388.38,390.8 1 1 +github.com/echovault/echovault/internal/modules/admin/commands.go:391.7,391.30 1 1 github.com/echovault/echovault/internal/modules/string/commands.go:24.72,26.16 2 1 github.com/echovault/echovault/internal/modules/string/commands.go:26.16,28.3 1 0 github.com/echovault/echovault/internal/modules/string/commands.go:30.2,34.9 4 1 @@ -2597,99 +2253,443 @@ github.com/echovault/echovault/internal/modules/sorted_set/utils.go:162.3,162.13 github.com/echovault/echovault/internal/modules/sorted_set/utils.go:163.12,164.16 1 1 github.com/echovault/echovault/internal/modules/sorted_set/utils.go:164.16,166.4 1 1 github.com/echovault/echovault/internal/modules/sorted_set/utils.go:167.3,167.13 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:27.78,33.29 4 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:33.29,34.54 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:34.54,40.42 4 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:40.42,42.5 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:44.4,47.12 3 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:50.3,50.36 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:50.36,57.43 5 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:57.43,59.5 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:61.4,63.21 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:67.2,69.25 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:72.76,76.35 3 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:76.35,77.65 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:77.65,78.41 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:78.41,80.5 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:81.4,81.12 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:83.3,83.13 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:86.2,86.51 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:89.75,90.29 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:91.9,96.36 4 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:96.36,97.66 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:97.66,98.52 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:98.52,102.6 3 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:103.5,103.13 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:105.4,106.14 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:108.3,109.26 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:111.9,115.56 3 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:115.56,117.4 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:118.3,118.53 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:118.53,122.37 3 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:122.37,123.67 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:123.67,124.53 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:124.53,125.59 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:125.59,129.8 3 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:131.6,131.14 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:133.5,133.54 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:133.54,136.6 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:138.9,138.61 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:138.61,142.37 3 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:142.37,143.67 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:143.67,144.53 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:144.53,146.24 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:146.24,149.8 2 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:151.6,151.14 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:153.5,153.33 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:153.33,156.6 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:158.9,158.60 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:158.60,162.37 3 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:162.37,163.67 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:163.67,164.53 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:164.53,165.55 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:165.55,169.8 3 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:171.6,171.14 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:173.5,173.50 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:173.50,176.6 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:178.9,180.4 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:181.3,182.26 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:183.10,184.54 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:188.75,190.2 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:192.36,200.84 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:200.84,204.5 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:213.84,217.5 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:225.86,229.7 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:238.86,242.7 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:252.86,256.7 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:267.84,271.5 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:272.73,273.49 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:273.49,275.6 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:276.5,276.45 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:285.84,289.5 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:290.73,292.18 2 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:292.18,294.6 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:295.5,295.53 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:304.84,308.5 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:309.73,310.47 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:310.47,312.6 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:313.5,313.45 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:321.84,325.5 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:335.86,339.7 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:340.75,341.34 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:341.34,343.8 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:344.7,345.34 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:345.34,347.8 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:348.7,348.75 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:348.75,350.8 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:351.7,351.47 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:361.86,365.7 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:366.75,367.35 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:367.35,369.8 1 0 -github.com/echovault/echovault/internal/modules/admin/commands.go:370.7,371.47 2 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:380.86,384.7 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:385.75,388.38 3 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:388.38,390.8 1 1 -github.com/echovault/echovault/internal/modules/admin/commands.go:391.7,391.30 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:52.40,57.24 3 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:57.24,65.3 2 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:68.2,68.28 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:68.28,70.54 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:70.54,71.14 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:72.9,73.17 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:73.17,74.37 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:74.37,76.6 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:79.4,81.22 2 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:81.22,82.61 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:82.61,84.6 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:87.4,87.39 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:87.39,88.61 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:88.61,90.6 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:96.2,97.29 2 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:97.29,98.33 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:98.33,100.9 2 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:103.2,103.20 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:103.20,105.3 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:108.2,108.29 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:108.29,110.3 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:112.2,122.13 3 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:125.52,130.70 3 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:130.70,132.3 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:133.2,137.3 2 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:140.45,146.33 3 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:146.33,147.30 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:147.30,148.47 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:148.47,150.5 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:150.10,153.5 2 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:157.2,158.45 2 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:158.45,160.3 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:162.2,169.12 4 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:172.41,177.2 3 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:179.73,184.37 4 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:184.37,185.28 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:185.28,187.12 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:190.3,190.31 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:190.31,191.30 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:191.30,193.5 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:196.3,196.18 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:196.18,197.12 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:200.3,200.52 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:200.52,201.49 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:201.49,203.5 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:206.3,206.63 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:206.63,208.4 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:210.2,210.12 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:213.95,222.19 6 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:222.19,230.60 3 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:230.60,232.4 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:233.3,233.24 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:236.2,236.19 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:236.19,245.31 4 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:245.31,246.28 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:246.28,249.10 3 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:252.3,252.17 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:252.17,254.4 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:258.2,258.19 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:258.19,260.3 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:263.2,263.21 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:263.21,269.3 2 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:271.2,271.46 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:271.46,272.38 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:272.38,275.18 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:275.18,282.5 2 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:286.2,286.50 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:289.131,298.16 6 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:298.16,300.3 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:302.2,306.59 4 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:306.59,310.17 4 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:310.17,312.4 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:316.2,316.36 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:316.36,318.3 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:321.2,321.43 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:321.43,323.3 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:326.2,326.37 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:326.37,328.3 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:331.2,334.29 2 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:334.29,336.3 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:339.2,339.57 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:339.57,341.3 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:344.2,345.65 2 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:345.65,346.101 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:346.101,347.63 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:347.63,349.5 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:350.4,351.16 2 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:353.5,354.27 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:354.27,356.4 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:357.3,357.88 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:361.2,361.64 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:361.64,362.101 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:362.101,363.63 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:363.63,366.5 2 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:367.4,367.16 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:369.5,371.3 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:374.2,374.94 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:374.94,376.3 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:376.5,378.3 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:381.2,381.93 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:381.93,383.3 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:383.5,385.3 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:388.2,388.59 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:388.59,390.36 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:390.36,392.106 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:392.106,394.5 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:394.7,396.5 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:398.4,398.105 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:398.105,400.5 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:400.7,402.5 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:404.3,404.13 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:407.2,407.45 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:407.45,409.29 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:409.29,411.4 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:414.3,414.59 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:414.59,415.95 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:415.95,416.49 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:416.49,418.6 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:419.5,420.17 2 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:422.6,424.4 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:427.3,427.60 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:427.60,428.97 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:428.97,429.50 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:429.50,431.6 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:432.5,433.17 2 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:435.6,437.4 1 0 +github.com/echovault/echovault/internal/modules/acl/acl.go:440.2,440.12 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:443.32,447.33 3 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:447.33,452.31 5 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:452.31,453.37 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:453.37,455.5 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:457.3,457.25 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:460.2,460.29 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:460.29,461.33 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:461.33,463.4 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:467.29,469.2 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:471.31,473.2 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:475.30,477.2 1 1 +github.com/echovault/echovault/internal/modules/acl/acl.go:479.32,481.2 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:31.68,32.56 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:32.56,34.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:35.2,36.9 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:36.9,38.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:39.2,39.102 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:39.102,41.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:42.2,42.42 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:45.71,46.30 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:46.30,48.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:50.2,51.9 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:51.9,53.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:55.2,57.30 3 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:57.30,58.38 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:58.38,61.9 3 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:65.2,65.16 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:65.16,67.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:70.2,74.18 3 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:74.18,76.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:76.8,78.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:79.2,79.21 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:79.21,81.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:82.2,82.17 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:82.17,84.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:86.2,87.29 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:87.29,89.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:92.2,93.51 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:93.51,94.22 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:94.22,96.12 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:98.3,98.49 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:100.2,100.51 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:100.51,101.22 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:101.22,103.12 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:105.3,105.49 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:109.2,110.48 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:110.48,111.21 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:111.21,113.12 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:115.3,115.47 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:117.2,117.48 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:117.48,118.21 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:118.21,120.12 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:122.3,122.47 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:126.2,127.79 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:127.79,128.37 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:128.37,130.4 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:132.2,133.30 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:133.30,134.10 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:135.100,137.53 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:138.53,140.52 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:141.52,143.52 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:148.2,150.54 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:150.54,152.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:153.2,153.54 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:153.54,155.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:157.2,159.25 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:162.67,163.29 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:163.29,165.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:167.2,171.35 3 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:171.35,172.36 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:172.36,173.48 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:173.48,175.5 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:176.4,176.12 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:178.3,178.50 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:178.50,179.51 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:179.51,182.5 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:186.2,186.30 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:186.30,189.34 3 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:189.34,192.4 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:193.3,194.28 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:194.28,196.24 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:196.24,198.5 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:200.3,200.26 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:203.2,203.30 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:203.30,205.46 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:205.46,206.54 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:206.54,208.38 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:208.38,210.30 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:210.30,212.7 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:214.5,214.28 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:219.2,219.85 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:222.69,224.9 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:224.9,226.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:227.2,228.33 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:228.33,230.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:231.2,232.25 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:235.71,237.9 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:237.9,239.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:240.2,240.56 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:240.56,242.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:243.2,243.42 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:246.71,247.29 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:247.29,249.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:250.2,251.9 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:251.9,253.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:254.2,254.75 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:254.75,256.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:257.2,257.42 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:260.70,262.9 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:262.9,264.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:265.2,266.74 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:269.68,270.29 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:270.29,272.3 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:273.2,274.9 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:274.9,276.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:277.2,279.33 3 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:279.33,282.19 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:282.19,284.4 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:284.9,286.4 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:288.3,288.22 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:288.22,290.4 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:292.3,292.18 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:292.18,294.4 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:296.3,296.43 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:296.43,297.61 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:297.61,299.5 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:300.4,300.58 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:300.58,302.5 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:305.3,305.52 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:305.52,306.23 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:306.23,308.13 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:310.4,310.39 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:313.3,313.52 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:313.52,314.23 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:314.23,316.13 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:318.4,318.39 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:321.3,321.49 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:321.49,322.22 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:322.22,324.13 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:326.4,326.37 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:329.3,329.49 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:329.49,330.22 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:330.22,332.13 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:334.4,334.37 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:337.3,337.45 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:337.45,338.52 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:338.52,340.13 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:342.4,342.41 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:345.3,345.45 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:345.45,346.52 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:346.52,348.5 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:351.3,351.55 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:351.55,353.4 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:355.3,355.55 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:355.55,357.4 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:358.3,358.54 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:361.2,362.25 2 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:365.68,366.30 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:366.30,368.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:370.2,371.9 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:371.9,373.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:375.2,379.16 4 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:379.16,381.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:383.2,383.15 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:383.15,384.35 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:384.35,386.4 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:389.2,393.20 3 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:393.20,394.59 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:394.59,396.4 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:399.2,399.37 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:399.37,400.59 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:400.59,402.4 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:406.2,406.29 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:406.29,410.31 3 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:410.31,411.35 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:411.35,414.54 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:414.54,416.6 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:416.11,419.6 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:420.5,420.10 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:424.3,424.17 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:424.17,426.4 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:429.2,429.42 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:432.68,433.29 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:433.29,435.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:437.2,438.9 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:438.9,440.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:442.2,446.16 4 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:446.16,448.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:450.2,450.15 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:450.15,451.35 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:451.35,453.4 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:456.2,458.20 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:458.20,461.17 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:461.17,463.4 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:464.3,465.17 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:465.17,467.4 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:470.2,470.37 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:470.37,473.17 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:473.17,475.4 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:476.3,477.17 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:477.17,479.4 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:482.2,483.16 2 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:483.16,485.3 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:487.2,487.42 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:490.36,500.84 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:500.84,506.5 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:515.84,521.5 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:530.86,536.7 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:545.86,551.7 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:560.86,566.7 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:575.86,581.7 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:591.86,597.7 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:606.86,612.7 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:621.86,627.7 1 1 +github.com/echovault/echovault/internal/modules/acl/commands.go:639.86,645.7 1 0 +github.com/echovault/echovault/internal/modules/acl/commands.go:654.86,660.7 1 0 +github.com/echovault/echovault/internal/modules/acl/user.go:53.31,55.39 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:55.39,57.3 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:58.2,59.51 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:59.51,61.3 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:63.2,64.37 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:64.37,66.3 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:67.2,68.49 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:68.49,70.3 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:72.2,73.53 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:73.53,75.3 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:76.2,77.54 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:77.54,79.3 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:81.2,82.43 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:82.43,84.3 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:85.2,86.55 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:86.55,88.3 1 0 +github.com/echovault/echovault/internal/modules/acl/user.go:91.79,93.32 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:93.32,94.24 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:94.24,96.12 2 0 +github.com/echovault/echovault/internal/modules/acl/user.go:98.3,98.25 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:100.2,100.33 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:100.33,101.17 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:101.17,104.4 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:105.3,105.25 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:107.2,107.8 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:110.50,111.26 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:111.26,113.35 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:113.35,115.4 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:116.3,116.36 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:116.36,118.4 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:120.3,120.37 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:120.37,126.12 3 1 +github.com/echovault/echovault/internal/modules/acl/user.go:128.3,128.20 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:128.20,129.84 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:129.84,130.65 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:130.65,132.6 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:133.5,133.45 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:135.4,135.12 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:137.3,137.20 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:137.20,138.84 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:138.84,139.68 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:139.68,141.6 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:142.5,142.45 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:144.4,144.12 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:147.3,147.43 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:147.43,150.12 3 1 +github.com/echovault/echovault/internal/modules/acl/user.go:152.3,152.46 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:152.46,154.12 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:156.3,156.36 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:156.36,157.21 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:157.21,159.13 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:161.4,161.21 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:161.21,163.13 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:167.3,167.40 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:167.40,171.12 4 0 +github.com/echovault/echovault/internal/modules/acl/user.go:173.3,173.93 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:173.93,178.12 5 1 +github.com/echovault/echovault/internal/modules/acl/user.go:180.3,180.57 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:180.57,183.12 3 1 +github.com/echovault/echovault/internal/modules/acl/user.go:185.3,185.57 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:185.57,188.12 3 1 +github.com/echovault/echovault/internal/modules/acl/user.go:191.3,191.44 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:191.44,193.12 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:195.3,195.36 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:195.36,196.21 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:196.21,198.13 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:200.4,200.21 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:200.21,202.13 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:206.3,206.44 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:206.44,209.12 3 1 +github.com/echovault/echovault/internal/modules/acl/user.go:211.3,211.66 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:211.66,212.21 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:212.21,214.13 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:216.4,216.21 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:216.21,218.13 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:224.2,224.26 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:224.26,225.39 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:225.39,228.4 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:231.2,231.26 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:231.26,233.42 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:233.42,236.4 2 0 +github.com/echovault/echovault/internal/modules/acl/user.go:238.3,238.43 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:238.43,243.4 4 1 +github.com/echovault/echovault/internal/modules/acl/user.go:245.3,245.60 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:245.60,249.4 3 1 +github.com/echovault/echovault/internal/modules/acl/user.go:251.3,251.46 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:251.46,254.4 2 1 +github.com/echovault/echovault/internal/modules/acl/user.go:256.2,256.12 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:259.36,273.2 13 0 +github.com/echovault/echovault/internal/modules/acl/user.go:275.38,288.2 12 0 +github.com/echovault/echovault/internal/modules/acl/user.go:290.40,305.2 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:307.46,308.24 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:308.24,310.3 1 1 +github.com/echovault/echovault/internal/modules/acl/user.go:311.2,311.26 1 1 github.com/echovault/echovault/echovault/api_acl.go:126.71,128.23 2 1 github.com/echovault/echovault/echovault/api_acl.go:128.23,130.3 1 1 github.com/echovault/echovault/echovault/api_acl.go:131.2,132.16 2 1 diff --git a/internal/modules/acl/commands_test.go b/internal/modules/acl/commands_test.go index 83897a1..7e43efd 100644 --- a/internal/modules/acl/commands_test.go +++ b/internal/modules/acl/commands_test.go @@ -21,36 +21,16 @@ import ( "github.com/echovault/echovault/internal" "github.com/echovault/echovault/internal/config" "github.com/echovault/echovault/internal/constants" - "github.com/echovault/echovault/internal/modules/acl" + "github.com/tidwall/resp" "slices" - "sync" + "strings" + "testing" ) -var bindAddr string -var port uint16 -var mockServer *echovault.EchoVault - -func init() { - bindAddr = "localhost" - - p, _ := internal.GetFreePort() - port = uint16(p) - - mockServer = setUpServer(bindAddr, port, true, "") - - wg := sync.WaitGroup{} - wg.Add(1) - go func() { - wg.Done() - mockServer.Start() - }() - wg.Wait() -} - -func setUpServer(bindAddr string, port uint16, requirePass bool, aclConfig string) *echovault.EchoVault { +func setUpServer(port int, requirePass bool, aclConfig string) (*echovault.EchoVault, error) { conf := config.Config{ - BindAddr: bindAddr, - Port: port, + BindAddr: "localhost", + Port: uint16(port), DataDir: "", EvictionPolicy: constants.NoEviction, RequirePass: requirePass, @@ -58,46 +38,47 @@ func setUpServer(bindAddr string, port uint16, requirePass bool, aclConfig strin AclConfig: aclConfig, } - mockServer, _ := echovault.NewEchoVault( + mockServer, err := echovault.NewEchoVault( echovault.WithConfig(conf), ) + if err != nil { + return nil, err + } // Add the initial test users to the ACL module. - // a.AddUsers(generateInitialTestUsers()) + for _, user := range generateInitialTestUsers() { + if _, err := mockServer.ACLSetUser(user); err != nil { + return nil, err + } + } - return mockServer + return mockServer, nil } -func generateInitialTestUsers() []*acl.User { - // User with both hash password and plaintext password - withPasswordUser := acl.CreateUser("with_password_user") - h := sha256.New() - h.Write([]byte("password3")) - withPasswordUser.Passwords = []acl.Password{ - {PasswordType: acl.PasswordPlainText, PasswordValue: "password2"}, - {PasswordType: acl.PasswordSHA256, PasswordValue: string(h.Sum(nil))}, - } - withPasswordUser.IncludedCategories = []string{"*"} - withPasswordUser.IncludedCommands = []string{"*"} - - // User with NoPassword option - noPasswordUser := acl.CreateUser("no_password_user") - noPasswordUser.Passwords = []acl.Password{ - {PasswordType: acl.PasswordPlainText, PasswordValue: "password4"}, - } - noPasswordUser.NoPassword = true - - // Disabled user - disabledUser := acl.CreateUser("disabled_user") - disabledUser.Passwords = []acl.Password{ - {PasswordType: acl.PasswordPlainText, PasswordValue: "password5"}, - } - disabledUser.Enabled = false - - return []*acl.User{ - withPasswordUser, - noPasswordUser, - disabledUser, +func generateInitialTestUsers() []echovault.User { + return []echovault.User{ + { + // User with both hash password and plaintext password. + Username: "with_password_user", + Enabled: true, + IncludeCategories: []string{"*"}, + IncludeCommands: []string{"*"}, + AddPlainPasswords: []string{"password2"}, + AddHashPasswords: []string{generateSHA256Password("password3")}, + }, + { + // User with NoPassword option. + Username: "no_password_user", + Enabled: true, + NoPassword: true, + AddPlainPasswords: []string{"password4"}, + }, + { + // Disabled user. + Username: "disabled_user", + Enabled: false, + AddPlainPasswords: []string{"password5"}, + }, } } @@ -125,47 +106,36 @@ func compareSlices[T comparable](res, expected []T) error { } // compareUsers compares 2 users and checks if all their fields are equal -func compareUsers(user1, user2 *acl.User) error { +func compareUsers(user1, user2 map[string][]string) error { // Compare flags - if user1.Username != user2.Username { - return fmt.Errorf("mismatched usernames \"%s\", and \"%s\"", user1.Username, user2.Username) - } - if user1.Enabled != user2.Enabled { - return fmt.Errorf("mismatched enabled flag \"%+v\", and \"%+v\"", user1.Enabled, user2.Enabled) - } - if user1.NoPassword != user2.NoPassword { - return fmt.Errorf("mismatched nopassword flag \"%+v\", and \"%+v\"", user1.NoPassword, user2.NoPassword) - } - if user1.NoKeys != user2.NoKeys { - return fmt.Errorf("mismatched nokeys flag \"%+v\", and \"%+v\"", user1.NoKeys, user2.NoKeys) + if user1["username"][0] != user2["username"][0] { + return fmt.Errorf("mismatched usernames \"%s\", and \"%s\"", user1["username"][0], user2["username"][0]) } - // Compare passwords - for _, password1 := range user1.Passwords { - if !slices.ContainsFunc(user2.Passwords, func(password2 acl.Password) bool { - return password1.PasswordType == password2.PasswordType && password1.PasswordValue == password2.PasswordValue - }) { - return fmt.Errorf("found password %+v in user1 that was not found in user2", password1) - } + // Check if both users are enabled. + if slices.Contains(user1["flags"], "on") != slices.Contains(user2["flags"], "on") { + return fmt.Errorf("mismatched enabled flag \"%+v\", and \"%+v\"", + slices.Contains(user1["flags"], "on"), slices.Contains(user2["flags"], "on")) } - for _, password2 := range user2.Passwords { - if !slices.ContainsFunc(user1.Passwords, func(password1 acl.Password) bool { - return password1.PasswordType == password2.PasswordType && password1.PasswordValue == password2.PasswordValue - }) { - return fmt.Errorf("found password %+v in user2 that was not found in user1", password2) - } + + // Check if "nokeys" is present + if slices.Contains(user1["flags"], "nokeys") != slices.Contains(user2["flags"], "nokeys") { + return fmt.Errorf("mismatched nokeys flag \"%+v\", and \"%+v\"", + slices.Contains(user1["flags"], "nokeys"), slices.Contains(user2["flags"], "nokeys")) + } + + // Check if "nopass" is present + if slices.Contains(user1["flags"], "nopass") != slices.Contains(user1["flags"], "nopass") { + return fmt.Errorf("mismatched nopassword flag \"%+v\", and \"%+v\"", + slices.Contains(user1["flags"], "nopass"), slices.Contains(user1["flags"], "nopass")) } // Compare permissions permissions := [][][]string{ - {user1.IncludedCategories, user2.IncludedCategories}, - {user1.ExcludedCategories, user2.ExcludedCategories}, - {user1.IncludedCommands, user2.IncludedCommands}, - {user1.ExcludedCommands, user2.ExcludedCommands}, - {user1.IncludedReadKeys, user2.IncludedReadKeys}, - {user1.IncludedWriteKeys, user2.IncludedWriteKeys}, - {user1.IncludedPubSubChannels, user2.IncludedPubSubChannels}, - {user1.ExcludedPubSubChannels, user2.ExcludedPubSubChannels}, + {user1["categories"], user2["categories"]}, + {user1["commands"], user2["commands"]}, + {user1["keys"], user2["keys"]}, + {user1["channels"], user2["channels"]}, } for _, p := range permissions { if err := compareSlices(p[0], p[1]); err != nil { @@ -182,1306 +152,1400 @@ func generateSHA256Password(plain string) string { return string(h.Sum(nil)) } -// func Test_HandleAuth(t *testing.T) { -// conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", bindAddr, port)) -// if err != nil { -// t.Error(err) -// return -// } -// -// defer func() { -// if conn != nil { -// _ = conn.Close() -// } -// }() -// -// r := resp.NewConn(conn) -// -// tests := []struct { -// cmd []resp.Value -// wantRes string -// wantErr string -// }{ -// { // 1. Authenticate with default user without specifying username -// cmd: []resp.Value{resp.StringValue("AUTH"), resp.StringValue("password1")}, -// wantRes: "OK", -// wantErr: "", -// }, -// { // 2. Authenticate with plaintext password -// cmd: []resp.Value{ -// resp.StringValue("AUTH"), -// resp.StringValue("with_password_user"), -// resp.StringValue("password2"), -// }, -// wantRes: "OK", -// wantErr: "", -// }, -// { // 3. Authenticate with SHA256 password -// cmd: []resp.Value{ -// resp.StringValue("AUTH"), -// resp.StringValue("with_password_user"), -// resp.StringValue("password3"), -// }, -// wantRes: "OK", -// wantErr: "", -// }, -// { // 4. Authenticate with no password user -// cmd: []resp.Value{ -// resp.StringValue("AUTH"), -// resp.StringValue("no_password_user"), -// resp.StringValue("password4"), -// }, -// wantRes: "OK", -// wantErr: "", -// }, -// { // 5. Fail to authenticate with disabled user -// cmd: []resp.Value{ -// resp.StringValue("AUTH"), -// resp.StringValue("disabled_user"), -// resp.StringValue("password5"), -// }, -// wantRes: "", -// wantErr: "Error user disabled_user is disabled", -// }, -// { // 6. Fail to authenticate with non-existent user -// cmd: []resp.Value{ -// resp.StringValue("AUTH"), -// resp.StringValue("non_existent_user"), -// resp.StringValue("password6"), -// }, -// wantRes: "", -// wantErr: "Error no user with username non_existent_user", -// }, -// { // 7. Command too short -// cmd: []resp.Value{resp.StringValue("AUTH")}, -// wantRes: "", -// wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse), -// }, -// { // 8. Command too long -// cmd: []resp.Value{ -// resp.StringValue("AUTH"), -// resp.StringValue("user"), -// resp.StringValue("password1"), -// resp.StringValue("password2"), -// }, -// wantRes: "", -// wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse), -// }, -// } -// -// for _, test := range tests { -// if err = r.WriteArray(test.cmd); err != nil { -// t.Error(err) -// } -// rv, _, err := r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// if test.wantErr != "" { -// if rv.Error().Error() != test.wantErr { -// t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, rv.Error().Error()) -// } -// continue -// } -// if rv.String() != test.wantRes { -// t.Errorf("expected response \"%s\", got \"%s\"", test.wantRes, rv.String()) -// } -// } -// } +func Test_ACL(t *testing.T) { + port, err := internal.GetFreePort() + if err != nil { + t.Error(err) + return + } -// func Test_HandleCat(t *testing.T) { -// conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", bindAddr, port)) -// if err != nil { -// t.Error(err) -// return -// } -// defer func() { -// if conn != nil { -// _ = conn.Close() -// } -// }() -// r := resp.NewConn(conn) -// -// // Authenticate connection -// if err = r.WriteArray([]resp.Value{resp.StringValue("AUTH"), resp.StringValue("password1")}); err != nil { -// t.Error(err) -// } -// rv, _, err := r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// if rv.String() != "OK" { -// t.Error("could not authenticate user") -// } -// -// // Since only ACL commands are loaded in this test suite, this test will only test against the -// // list of categories and commands available in the ACL module. -// tests := []struct { -// cmd []resp.Value -// wantRes []string -// wantErr string -// }{ -// { // 1. Return list of categories -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT")}, -// wantRes: []string{ -// constants.ConnectionCategory, -// constants.SlowCategory, -// constants.FastCategory, -// constants.AdminCategory, -// constants.DangerousCategory, -// }, -// wantErr: "", -// }, -// { // 2. Return list of commands in connection category -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.ConnectionCategory)}, -// wantRes: []string{"auth"}, -// wantErr: "", -// }, -// { // 3. Return list of commands in slow category -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.SlowCategory)}, -// wantRes: []string{"auth", "acl|cat", "acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"}, -// wantErr: "", -// }, -// { // 4. Return list of commands in fast category -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.FastCategory)}, -// wantRes: []string{"acl|whoami"}, -// wantErr: "", -// }, -// { // 5. Return list of commands in admin category -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.AdminCategory)}, -// wantRes: []string{"acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"}, -// wantErr: "", -// }, -// { // 6. Return list of commands in dangerous category -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.DangerousCategory)}, -// wantRes: []string{"acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"}, -// wantErr: "", -// }, -// { // 7. Return error when category does not exist -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue("non-existent")}, -// wantRes: nil, -// wantErr: "Error category NON-EXISTENT not found", -// }, -// { // 8. Command too long -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue("category1"), resp.StringValue("category2")}, -// wantRes: nil, -// wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse), -// }, -// } -// -// for _, test := range tests { -// if err = r.WriteArray(test.cmd); err != nil { -// t.Error(err) -// } -// rv, _, err = r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// if test.wantErr != "" { -// if rv.Error().Error() != test.wantErr { -// t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, rv.Error().Error()) -// } -// continue -// } -// resArr := rv.Array() -// // Check if all the elements in the expected array are in the response array -// for _, expected := range test.wantRes { -// if !slices.ContainsFunc(resArr, func(value resp.Value) bool { -// return value.String() == expected -// }) { -// t.Errorf("could not find expected command \"%s\" in the response array for category", expected) -// } -// } -// } -// } + mockServer, err := setUpServer(port, true, "") + if err != nil { + t.Error(err) + return + } -// func Test_HandleUsers(t *testing.T) { -// port, _ := internal.GetFreePort() -// mockServer := setUpServer(bindAddr, uint16(port), false, "") -// wg := sync.WaitGroup{} -// wg.Add(1) -// go func() { -// wg.Done() -// mockServer.Start() -// }() -// wg.Wait() -// -// conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", bindAddr, port)) -// if err != nil { -// t.Error(err) -// return -// } -// -// defer func() { -// if conn != nil { -// _ = conn.Close() -// } -// }() -// -// r := resp.NewConn(conn) -// -// users := []string{"default", "with_password_user", "no_password_user", "disabled_user"} -// -// if err = r.WriteArray([]resp.Value{resp.StringValue("ACL"), resp.StringValue("USERS")}); err != nil { -// t.Error(err) -// } -// -// rv, _, err := r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// -// resArr := rv.Array() -// -// // Check if all the expected users are in the response array -// for _, user := range users { -// if !slices.ContainsFunc(resArr, func(value resp.Value) bool { -// return value.String() == user -// }) { -// t.Errorf("could not find expected user \"%s\" in response array", user) -// } -// } -// -// // Check if all the users in the response array are in the expected users -// for _, value := range resArr { -// if !slices.ContainsFunc(users, func(user string) bool { -// return value.String() == user -// }) { -// t.Errorf("could not find response user \"%s\" in expected users array", value.String()) -// } -// } -// } + go func() { + mockServer.Start() + }() -// func Test_HandleSetUser(t *testing.T) { -// port, _ := internal.GetFreePort() -// mockServer := setUpServer(bindAddr, uint16(port), false, "") -// wg := sync.WaitGroup{} -// wg.Add(1) -// go func() { -// wg.Done() -// mockServer.Start() -// }() -// wg.Wait() -// -// a := getACL(mockServer) -// -// conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", bindAddr, port)) -// if err != nil { -// t.Error(err) -// return -// } -// defer func() { -// if conn != nil { -// _ = conn.Close() -// } -// }() -// -// r := resp.NewConn(conn) -// -// tests := []struct { -// presetUser *acl.User -// cmd []resp.Value -// wantRes string -// wantErr string -// wantUser *acl.User -// }{ -// { -// // 1. Create new enabled user -// presetUser: nil, -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("SETUSER"), -// resp.StringValue("set_user_1"), -// resp.StringValue("on"), -// }, -// wantRes: "OK", -// wantErr: "", -// wantUser: func() *acl.User { -// user := acl.CreateUser("set_user_1") -// user.Enabled = true -// user.Normalise() -// return user -// }(), -// }, -// { -// // 2. Create new disabled user -// presetUser: nil, -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("SETUSER"), -// resp.StringValue("set_user_2"), -// resp.StringValue("off"), -// }, -// wantRes: "OK", -// wantErr: "", -// wantUser: func() *acl.User { -// user := acl.CreateUser("set_user_2") -// user.Enabled = false -// user.Normalise() -// return user -// }(), -// }, -// { -// // 3. Create new enabled user with both plaintext and SHA256 passwords -// presetUser: nil, -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("SETUSER"), -// resp.StringValue("set_user_3"), -// resp.StringValue("on"), -// resp.StringValue(">set_user_3_plaintext_password_1"), -// resp.StringValue(">set_user_3_plaintext_password_2"), -// resp.StringValue(fmt.Sprintf("#%s", generateSHA256Password("set_user_3_hash_password_1"))), -// resp.StringValue(fmt.Sprintf("#%s", generateSHA256Password("set_user_3_hash_password_2"))), -// }, -// wantRes: "OK", -// wantErr: "", -// wantUser: func() *acl.User { -// user := acl.CreateUser("set_user_3") -// user.Enabled = true -// user.Passwords = []acl.Password{ -// {PasswordType: acl.PasswordPlainText, PasswordValue: "set_user_3_plaintext_password_1"}, -// {PasswordType: acl.PasswordPlainText, PasswordValue: "set_user_3_plaintext_password_2"}, -// {PasswordType: acl.PasswordSHA256, PasswordValue: generateSHA256Password("set_user_3_hash_password_1")}, -// {PasswordType: acl.PasswordSHA256, PasswordValue: generateSHA256Password("set_user_3_hash_password_2")}, -// } -// user.Normalise() -// return user -// }(), -// }, -// { -// // 4. Remove plaintext and SHA256 password from existing user -// presetUser: func() *acl.User { -// user := acl.CreateUser("set_user_4") -// user.Enabled = true -// user.Passwords = []acl.Password{ -// {PasswordType: acl.PasswordPlainText, PasswordValue: "set_user_3_plaintext_password_1"}, -// {PasswordType: acl.PasswordPlainText, PasswordValue: "set_user_3_plaintext_password_2"}, -// {PasswordType: acl.PasswordSHA256, PasswordValue: generateSHA256Password("set_user_3_hash_password_1")}, -// {PasswordType: acl.PasswordSHA256, PasswordValue: generateSHA256Password("set_user_3_hash_password_2")}, -// } -// user.Normalise() -// return user -// }(), -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("SETUSER"), -// resp.StringValue("set_user_4"), -// resp.StringValue("on"), -// resp.StringValue("password1"), -// resp.StringValue(fmt.Sprintf("#%s", generateSHA256Password("password2"))), -// }, -// wantRes: "OK", -// wantErr: "", -// wantUser: func() *acl.User { -// user := acl.CreateUser("set_user_16") -// user.Enabled = true -// user.NoPassword = true -// user.Passwords = []acl.Password{} -// user.Normalise() -// return user -// }(), -// }, -// { -// // 17. Delete all existing users passwords using 'nopass' -// presetUser: func() *acl.User { -// user := acl.CreateUser("set_user_17") -// user.Enabled = true -// user.NoPassword = true -// user.Passwords = []acl.Password{ -// {PasswordType: acl.PasswordPlainText, PasswordValue: "password1"}, -// {PasswordType: acl.PasswordSHA256, PasswordValue: generateSHA256Password("password2")}, -// } -// user.Normalise() -// return user -// }(), -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("SETUSER"), -// resp.StringValue("set_user_17"), -// resp.StringValue("on"), -// resp.StringValue("nopass"), -// }, -// wantRes: "OK", -// wantErr: "", -// wantUser: func() *acl.User { -// user := acl.CreateUser("set_user_17") -// user.Enabled = true -// user.NoPassword = true -// user.Passwords = []acl.Password{} -// user.Normalise() -// return user -// }(), -// }, -// { -// // 18. Clear all of an existing user's passwords using 'resetpass' -// presetUser: func() *acl.User { -// user := acl.CreateUser("set_user_18") -// user.Enabled = true -// user.NoPassword = true -// user.Passwords = []acl.Password{ -// {PasswordType: acl.PasswordPlainText, PasswordValue: "password1"}, -// {PasswordType: acl.PasswordSHA256, PasswordValue: generateSHA256Password("password2")}, -// } -// user.Normalise() -// return user -// }(), -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("SETUSER"), -// resp.StringValue("set_user_18"), -// resp.StringValue("on"), -// resp.StringValue("nopass"), -// }, -// wantRes: "OK", -// wantErr: "", -// wantUser: func() *acl.User { -// user := acl.CreateUser("set_user_18") -// user.Enabled = true -// user.NoPassword = true -// user.Passwords = []acl.Password{} -// user.Normalise() -// return user -// }(), -// }, -// { -// // 19. Clear all of an existing user's command privileges using 'nocommands' -// presetUser: func() *acl.User { -// user := acl.CreateUser("set_user_19") -// user.Enabled = true -// user.IncludedCommands = []string{"acl|getuser", "acl|setuser", "acl|deluser"} -// user.ExcludedCommands = []string{"rewriteaof", "save"} -// user.Normalise() -// return user -// }(), -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("SETUSER"), -// resp.StringValue("set_user_19"), -// resp.StringValue("on"), -// resp.StringValue("nocommands"), -// }, -// wantRes: "OK", -// wantErr: "", -// wantUser: func() *acl.User { -// user := acl.CreateUser("set_user_19") -// user.Enabled = true -// user.IncludedCommands = []string{} -// user.ExcludedCommands = []string{"*"} -// user.IncludedCategories = []string{} -// user.ExcludedCategories = []string{"*"} -// user.Normalise() -// return user -// }(), -// }, -// { -// // 20. Clear all of an existing user's allowed keys using 'resetkeys' -// presetUser: func() *acl.User { -// user := acl.CreateUser("set_user_20") -// user.Enabled = true -// user.IncludedWriteKeys = []string{"key1", "key2", "key3", "key4", "key5", "key6"} -// user.IncludedReadKeys = []string{"key1", "key2", "key3", "key7", "key8", "key9"} -// user.Normalise() -// return user -// }(), -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("SETUSER"), -// resp.StringValue("set_user_20"), -// resp.StringValue("on"), -// resp.StringValue("resetkeys"), -// }, -// wantRes: "OK", -// wantErr: "", -// wantUser: func() *acl.User { -// user := acl.CreateUser("set_user_20") -// user.Enabled = true -// user.NoKeys = true -// user.IncludedReadKeys = []string{} -// user.IncludedWriteKeys = []string{} -// user.Normalise() -// return user -// }(), -// }, -// { -// // 21. Allow user to access all channels using 'resetchannels' -// presetUser: func() *acl.User { -// user := acl.CreateUser("set_user_21") -// user.IncludedPubSubChannels = []string{"channel1", "channel2"} -// user.ExcludedPubSubChannels = []string{"channel3", "channel4"} -// user.Normalise() -// return user -// }(), -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("SETUSER"), -// resp.StringValue("set_user_21"), -// resp.StringValue("resetchannels"), -// }, -// wantRes: "OK", -// wantErr: "", -// wantUser: func() *acl.User { -// user := acl.CreateUser("set_user_21") -// user.IncludedPubSubChannels = []string{} -// user.ExcludedPubSubChannels = []string{"*"} -// user.Normalise() -// return user -// }(), -// }, -// } -// -// for i, test := range tests { -// if test.presetUser != nil { -// a.AddUsers([]*acl.User{test.presetUser}) -// } -// if err = r.WriteArray(test.cmd); err != nil { -// t.Error(err) -// } -// v, _, err := r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// if test.wantErr != "" { -// if v.Error().Error() != test.wantErr { -// t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, v.Error().Error()) -// } -// continue -// } -// if v.String() != test.wantRes { -// t.Errorf("expected response \"%s\", got \"%s\"", test.wantRes, v.String()) -// } -// if test.wantUser == nil { -// continue -// } -// expectedUser := test.wantUser -// currUserIdx := slices.IndexFunc(a.Users, func(user *acl.User) bool { -// return user.Username == expectedUser.Username -// }) -// if currUserIdx == -1 { -// t.Errorf("expected to find user with username \"%s\" but could not find them.", expectedUser.Username) -// } -// if err = compareUsers(expectedUser, a.Users[currUserIdx]); err != nil { -// t.Errorf("test idx: %d, %+v", i, err) -// } -// } -// } + t.Cleanup(func() { + mockServer.ShutDown() + }) -// func Test_HandleGetUser(t *testing.T) { -// port, _ := internal.GetFreePort() -// mockServer := setUpServer(bindAddr, uint16(port), false, "") -// wg := sync.WaitGroup{} -// wg.Add(1) -// go func() { -// wg.Done() -// mockServer.Start() -// }() -// wg.Wait() -// -// a := getACL(mockServer) -// -// conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", bindAddr, port)) -// if err != nil { -// t.Error(err) -// return -// } -// defer func() { -// if conn != nil { -// _ = conn.Close() -// } -// }() -// -// r := resp.NewConn(conn) -// -// tests := []struct { -// presetUser *acl.User -// cmd []resp.Value -// wantRes []resp.Value -// wantErr string -// }{ -// { // 1. Get the user and all their details -// presetUser: &acl.User{ -// Username: "get_user_1", -// Enabled: true, -// NoPassword: false, -// NoKeys: false, -// Passwords: []acl.Password{ -// {PasswordType: acl.PasswordPlainText, PasswordValue: "get_user_password_1"}, -// {PasswordType: acl.PasswordSHA256, PasswordValue: generateSHA256Password("get_user_password_2")}, -// }, -// IncludedCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory}, -// ExcludedCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory}, -// IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, -// ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, -// IncludedReadKeys: []string{"key1", "key2", "key3", "key4"}, -// IncludedWriteKeys: []string{"key1", "key2", "key5", "key6"}, -// IncludedPubSubChannels: []string{"channel1", "channel2"}, -// ExcludedPubSubChannels: []string{"channel3", "channel4"}, -// }, -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("GETUSER"), resp.StringValue("get_user_1")}, -// wantRes: []resp.Value{ -// resp.StringValue("username"), -// resp.ArrayValue([]resp.Value{resp.StringValue("get_user_1")}), -// resp.StringValue("flags"), -// resp.ArrayValue([]resp.Value{ -// resp.StringValue("on"), -// }), -// resp.StringValue("categories"), -// resp.ArrayValue([]resp.Value{ -// resp.StringValue(fmt.Sprintf("+@%s", constants.WriteCategory)), -// resp.StringValue(fmt.Sprintf("+@%s", constants.ReadCategory)), -// resp.StringValue(fmt.Sprintf("+@%s", constants.PubSubCategory)), -// resp.StringValue(fmt.Sprintf("-@%s", constants.AdminCategory)), -// resp.StringValue(fmt.Sprintf("-@%s", constants.ConnectionCategory)), -// resp.StringValue(fmt.Sprintf("-@%s", constants.DangerousCategory)), -// }), -// resp.StringValue("commands"), -// resp.ArrayValue([]resp.Value{ -// resp.StringValue("+acl|setuser"), -// resp.StringValue("+acl|getuser"), -// resp.StringValue("+acl|deluser"), -// resp.StringValue("-rewriteaof"), -// resp.StringValue("-save"), -// resp.StringValue("-acl|load"), -// resp.StringValue("-acl|save"), -// }), -// resp.StringValue("keys"), -// resp.ArrayValue([]resp.Value{ -// // Keys here -// resp.StringValue("%RW~key1"), -// resp.StringValue("%RW~key2"), -// resp.StringValue("%R~key3"), -// resp.StringValue("%R~key4"), -// resp.StringValue("%W~key5"), -// resp.StringValue("%W~key6"), -// }), -// resp.StringValue("channels"), -// resp.ArrayValue([]resp.Value{ -// // Channels here -// resp.StringValue("+&channel1"), -// resp.StringValue("+&channel2"), -// resp.StringValue("-&channel3"), -// resp.StringValue("-&channel4"), -// }), -// }, -// wantErr: "", -// }, -// { // 2. Return user not found error -// presetUser: nil, -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("GETUSER"), -// resp.StringValue("non_existent_user")}, -// wantRes: nil, -// wantErr: "Error user not found", -// }, -// } -// -// for _, test := range tests { -// if test.presetUser != nil { -// a.AddUsers([]*acl.User{test.presetUser}) -// } -// if err = r.WriteArray(test.cmd); err != nil { -// t.Error(err) -// } -// v, _, err := r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// if test.wantErr != "" { -// if v.Error().Error() != test.wantErr { -// t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, v.Error().Error()) -// } -// continue -// } -// resArr := v.Array() -// for i := 0; i < len(resArr); i++ { -// if slices.Contains([]string{"username", "flags", "categories", "commands", "keys", "channels"}, resArr[i].String()) { -// // String item -// if resArr[i].String() != test.wantRes[i].String() { -// t.Errorf("expected response component %+v, got %+v", test.wantRes[i], resArr[i]) -// } -// } else { -// // Array item -// var expected []string -// for _, item := range test.wantRes[i].Array() { -// expected = append(expected, item.String()) -// } -// -// var res []string -// for _, item := range resArr[i].Array() { -// res = append(res, item.String()) -// } -// -// if err = compareSlices(res, expected); err != nil { -// t.Error(err) -// } -// } -// } -// } -// } + t.Run("Test_HandleAuth", func(t *testing.T) { + conn, err := internal.GetConnection("localhost", port) + if err != nil { + t.Error(err) + return + } -// func Test_HandleDelUser(t *testing.T) { -// port, _ := internal.GetFreePort() -// mockServer := setUpServer(bindAddr, uint16(port), false, "") -// wg := sync.WaitGroup{} -// wg.Add(1) -// go func() { -// wg.Done() -// mockServer.Start() -// }() -// wg.Wait() -// -// a := getACL(mockServer) -// -// conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", bindAddr, port)) -// if err != nil { -// t.Error(err) -// return -// } -// defer func() { -// if conn != nil { -// _ = conn.Close() -// } -// }() -// -// r := resp.NewConn(conn) -// -// tests := []struct { -// presetUser *acl.User -// cmd []resp.Value -// wantRes string -// wantErr string -// }{ -// { -// // 1. Delete existing user while skipping default user and non-existent user -// presetUser: acl.CreateUser("user_to_delete"), -// cmd: []resp.Value{ -// resp.StringValue("ACL"), -// resp.StringValue("DELUSER"), -// resp.StringValue("default"), -// resp.StringValue("user_to_delete"), -// resp.StringValue("non_existent_user"), -// }, -// wantRes: "OK", -// wantErr: "", -// }, -// { -// // 2. Command too short -// presetUser: nil, -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("DELUSER")}, -// wantRes: "", -// wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse), -// }, -// } -// -// for _, test := range tests { -// if test.presetUser != nil { -// a.AddUsers([]*acl.User{test.presetUser}) -// } -// if err = r.WriteArray(test.cmd); err != nil { -// t.Error(err) -// } -// v, _, err := r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// if test.wantErr != "" { -// if v.Error().Error() != test.wantErr { -// t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, v.Error().Error()) -// } -// continue -// } -// // Check that default user still exists in the list of users -// if !slices.ContainsFunc(a.Users, func(user *acl.User) bool { -// return user.Username == "default" -// }) { -// t.Error("could not find user with username \"default\" in the ACL after deleting user") -// } -// // Check that the deleted user is no longer in the list -// if slices.ContainsFunc(a.Users, func(user *acl.User) bool { -// return user.Username == "user_to_delete" -// }) { -// t.Error("deleted user found in the ACL") -// } -// } -// } + defer func() { + if conn != nil { + _ = conn.Close() + } + }() -// func Test_HandleWhoAmI(t *testing.T) { -// conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", bindAddr, port)) -// if err != nil { -// t.Error(err) -// return -// } -// defer func() { -// if conn != nil { -// _ = conn.Close() -// } -// }() -// -// r := resp.NewConn(conn) -// -// tests := []struct { -// username string -// password string -// wantRes string -// }{ -// { // 1. With default user -// username: "default", -// password: "password1", -// wantRes: "default", -// }, -// { // 2. With user authenticated by plaintext password -// username: "with_password_user", -// password: "password2", -// wantRes: "with_password_user", -// }, -// { // 3. With user authenticated by SHA256 password -// username: "with_password_user", -// password: "password3", -// wantRes: "with_password_user", -// }, -// } -// -// for _, test := range tests { -// // Authenticate -// if err = r.WriteArray([]resp.Value{ -// resp.StringValue("AUTH"), -// resp.StringValue(test.username), -// resp.StringValue(test.password), -// }); err != nil { -// t.Error(err) -// } -// v, _, err := r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// if v.String() != "OK" { -// t.Errorf("expected response for auth with %s:%s to be \"OK\", got %s", test.username, test.password, v.String()) -// } -// // Check whoami response value -// if err = r.WriteArray([]resp.Value{resp.StringValue("ACL"), resp.StringValue("WHOAMI")}); err != nil { -// t.Error(err) -// } -// v, _, err = r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// if v.String() != test.wantRes { -// t.Errorf("expected whoami response to be \"%s\", got \"%s\"", test.wantRes, v.String()) -// } -// } -// } + r := resp.NewConn(conn) -// func Test_HandleList(t *testing.T) { -// port, _ := internal.GetFreePort() -// mockServer := setUpServer(bindAddr, uint16(port), false, "") -// wg := sync.WaitGroup{} -// wg.Add(1) -// go func() { -// wg.Done() -// mockServer.Start() -// }() -// wg.Wait() -// -// a := getACL(mockServer) -// -// conn, err := net.Dial("tcp", fmt.Sprintf("%s:%d", bindAddr, port)) -// if err != nil { -// t.Error(err) -// return -// } -// defer func() { -// if conn != nil { -// _ = conn.Close() -// } -// }() -// -// r := resp.NewConn(conn) -// -// tests := []struct { -// presetUsers []*acl.User -// cmd []resp.Value -// wantRes []string -// wantErr string -// }{ -// { // 1. Get the user and all their details -// presetUsers: []*acl.User{ -// { -// Username: "list_user_1", -// Enabled: true, -// NoPassword: false, -// NoKeys: false, -// Passwords: []acl.Password{ -// {PasswordType: acl.PasswordPlainText, PasswordValue: "list_user_password_1"}, -// {PasswordType: acl.PasswordSHA256, PasswordValue: generateSHA256Password("list_user_password_2")}, -// }, -// IncludedCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory}, -// ExcludedCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory}, -// IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, -// ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, -// IncludedReadKeys: []string{"key1", "key2", "key3", "key4"}, -// IncludedWriteKeys: []string{"key1", "key2", "key5", "key6"}, -// IncludedPubSubChannels: []string{"channel1", "channel2"}, -// ExcludedPubSubChannels: []string{"channel3", "channel4"}, -// }, -// { -// Username: "list_user_2", -// Enabled: true, -// NoPassword: true, -// NoKeys: true, -// Passwords: []acl.Password{}, -// IncludedCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory}, -// ExcludedCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory}, -// IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, -// ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, -// IncludedReadKeys: []string{}, -// IncludedWriteKeys: []string{}, -// IncludedPubSubChannels: []string{"channel1", "channel2"}, -// ExcludedPubSubChannels: []string{"channel3", "channel4"}, -// }, -// { -// Username: "list_user_3", -// Enabled: true, -// NoPassword: false, -// NoKeys: false, -// Passwords: []acl.Password{ -// {PasswordType: acl.PasswordPlainText, PasswordValue: "list_user_password_3"}, -// {PasswordType: acl.PasswordSHA256, PasswordValue: generateSHA256Password("list_user_password_4")}, -// }, -// IncludedCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory}, -// ExcludedCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory}, -// IncludedCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, -// ExcludedCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, -// IncludedReadKeys: []string{"key1", "key2", "key3", "key4"}, -// IncludedWriteKeys: []string{"key1", "key2", "key5", "key6"}, -// IncludedPubSubChannels: []string{"channel1", "channel2"}, -// ExcludedPubSubChannels: []string{"channel3", "channel4"}, -// }, -// }, -// cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("LIST")}, -// wantRes: []string{ -// "default on +@all +all %RW~* +&*", -// fmt.Sprintf("with_password_user on >password2 #%s +@all +all", generateSHA256Password("password3")), -// "no_password_user on nopass >password4", -// "disabled_user off >password5", -// fmt.Sprintf(`list_user_1 on >list_user_password_1 #%s +@write +@read +@pubsub -@admin -@connection -@dangerous +acl|setuser +acl|getuser +acl|deluser -rewriteaof -save -acl|load -acl|save %s +&channel1 +&channel2 -&channel3 -&channel4`, generateSHA256Password("list_user_password_2"), "%RW~key1 %RW~key2 %R~key3 %R~key4"), -// fmt.Sprintf(`list_user_2 on nopass nokeys +@write +@read +@pubsub -@admin -@connection -@dangerous +acl|setuser +acl|getuser +acl|deluser -rewriteaof -save -acl|load -acl|save +&channel1 +&channel2 -&channel3 -&channel4`), -// fmt.Sprintf(`list_user_3 on >list_user_password_3 #%s +@write +@read +@pubsub -@admin -@connection -@dangerous +acl|setuser +acl|getuser +acl|deluser -rewriteaof -save -acl|load -acl|save %s +&channel1 +&channel2 -&channel3 -&channel4`, generateSHA256Password("list_user_password_4"), "%RW~key1 %RW~key2 %R~key3 %R~key4"), -// }, -// wantErr: "", -// }, -// } -// -// for _, test := range tests { -// a.AddUsers(test.presetUsers) -// -// if err = r.WriteArray(test.cmd); err != nil { -// t.Error(err) -// } -// v, _, err := r.ReadValue() -// if err != nil { -// t.Error(err) -// } -// if test.wantErr != "" { -// if v.Error().Error() != test.wantErr { -// t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, v.Error().Error()) -// } -// continue -// } -// resArr := v.Array() -// if len(resArr) != len(test.wantRes) { -// t.Errorf("expected response of lenght %d, got lenght %d", len(test.wantRes), len(resArr)) -// } -// var resStr []string -// for i := 0; i < len(resArr); i++ { -// resStr = strings.Split(resArr[i].String(), " ") -// if !slices.ContainsFunc(test.wantRes, func(s string) bool { -// expectedUserSlice := strings.Split(s, " ") -// return compareSlices(resStr, expectedUserSlice) == nil -// }) { -// t.Errorf("could not find the following user in expected slice: %+v", resStr) -// } -// clear(resStr) -// } -// } -// } + tests := []struct { + cmd []resp.Value + wantRes string + wantErr string + }{ + { // 1. Authenticate with default user without specifying username + cmd: []resp.Value{resp.StringValue("AUTH"), resp.StringValue("password1")}, + wantRes: "OK", + wantErr: "", + }, + { // 2. Authenticate with plaintext password + cmd: []resp.Value{ + resp.StringValue("AUTH"), + resp.StringValue("with_password_user"), + resp.StringValue("password2"), + }, + wantRes: "OK", + wantErr: "", + }, + { // 3. Authenticate with SHA256 password + cmd: []resp.Value{ + resp.StringValue("AUTH"), + resp.StringValue("with_password_user"), + resp.StringValue("password3"), + }, + wantRes: "OK", + wantErr: "", + }, + { // 4. Authenticate with no password user + cmd: []resp.Value{ + resp.StringValue("AUTH"), + resp.StringValue("no_password_user"), + resp.StringValue("password4"), + }, + wantRes: "OK", + wantErr: "", + }, + { // 5. Fail to authenticate with disabled user + cmd: []resp.Value{ + resp.StringValue("AUTH"), + resp.StringValue("disabled_user"), + resp.StringValue("password5"), + }, + wantRes: "", + wantErr: "Error user disabled_user is disabled", + }, + { // 6. Fail to authenticate with non-existent user + cmd: []resp.Value{ + resp.StringValue("AUTH"), + resp.StringValue("non_existent_user"), + resp.StringValue("password6"), + }, + wantRes: "", + wantErr: "Error no user with username non_existent_user", + }, + { // 7. Command too short + cmd: []resp.Value{resp.StringValue("AUTH")}, + wantRes: "", + wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse), + }, + { // 8. Command too long + cmd: []resp.Value{ + resp.StringValue("AUTH"), + resp.StringValue("user"), + resp.StringValue("password1"), + resp.StringValue("password2"), + }, + wantRes: "", + wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse), + }, + } + + for _, test := range tests { + if err = r.WriteArray(test.cmd); err != nil { + t.Error(err) + } + rv, _, err := r.ReadValue() + if err != nil { + t.Error(err) + } + if test.wantErr != "" { + if rv.Error().Error() != test.wantErr { + t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, rv.Error().Error()) + } + continue + } + if rv.String() != test.wantRes { + t.Errorf("expected response \"%s\", got \"%s\"", test.wantRes, rv.String()) + } + } + }) + + t.Run("Test_HandleCat", func(t *testing.T) { + conn, err := internal.GetConnection("localhost", port) + if err != nil { + t.Error(err) + return + } + defer func() { + if conn != nil { + _ = conn.Close() + } + }() + r := resp.NewConn(conn) + + // Authenticate connection + if err = r.WriteArray([]resp.Value{resp.StringValue("AUTH"), resp.StringValue("password1")}); err != nil { + t.Error(err) + } + rv, _, err := r.ReadValue() + if err != nil { + t.Error(err) + } + if rv.String() != "OK" { + t.Error("could not authenticate user") + } + + // Since only ACL commands are loaded in this test suite, this test will only test against the + // list of categories and commands available in the ACL module. + tests := []struct { + cmd []resp.Value + wantRes []string + wantErr string + }{ + { // 1. Return list of categories + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT")}, + wantRes: []string{ + constants.ConnectionCategory, + constants.SlowCategory, + constants.FastCategory, + constants.AdminCategory, + constants.DangerousCategory, + }, + wantErr: "", + }, + { // 2. Return list of commands in connection category + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.ConnectionCategory)}, + wantRes: []string{"auth"}, + wantErr: "", + }, + { // 3. Return list of commands in slow category + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.SlowCategory)}, + wantRes: []string{"auth", "acl|cat", "acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"}, + wantErr: "", + }, + { // 4. Return list of commands in fast category + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.FastCategory)}, + wantRes: []string{"acl|whoami"}, + wantErr: "", + }, + { // 5. Return list of commands in admin category + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.AdminCategory)}, + wantRes: []string{"acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"}, + wantErr: "", + }, + { // 6. Return list of commands in dangerous category + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue(constants.DangerousCategory)}, + wantRes: []string{"acl|users", "acl|setuser", "acl|getuser", "acl|deluser", "acl|list", "acl|load", "acl|save"}, + wantErr: "", + }, + { // 7. Return error when category does not exist + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue("non-existent")}, + wantRes: nil, + wantErr: "Error category NON-EXISTENT not found", + }, + { // 8. Command too long + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("CAT"), resp.StringValue("category1"), resp.StringValue("category2")}, + wantRes: nil, + wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse), + }, + } + + for _, test := range tests { + if err = r.WriteArray(test.cmd); err != nil { + t.Error(err) + } + rv, _, err = r.ReadValue() + if err != nil { + t.Error(err) + } + if test.wantErr != "" { + if rv.Error().Error() != test.wantErr { + t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, rv.Error().Error()) + } + continue + } + resArr := rv.Array() + // Check if all the elements in the expected array are in the response array + for _, expected := range test.wantRes { + if !slices.ContainsFunc(resArr, func(value resp.Value) bool { + return value.String() == expected + }) { + t.Errorf("could not find expected command \"%s\" in the response array for category", expected) + } + } + } + }) + + t.Run("Test_HandleUsers", func(t *testing.T) { + port, err := internal.GetFreePort() + if err != nil { + t.Error(err) + return + } + + mockServer, err := setUpServer(port, false, "") + if err != nil { + t.Error(err) + return + } + + go func() { + mockServer.Start() + }() + + conn, err := internal.GetConnection("localhost", port) + if err != nil { + t.Error(err) + return + } + + defer func() { + if conn != nil { + _ = conn.Close() + } + }() + + r := resp.NewConn(conn) + + users := []string{"default", "with_password_user", "no_password_user", "disabled_user"} + + if err = r.WriteArray([]resp.Value{resp.StringValue("ACL"), resp.StringValue("USERS")}); err != nil { + t.Error(err) + } + + rv, _, err := r.ReadValue() + if err != nil { + t.Error(err) + } + + resArr := rv.Array() + + // Check if all the expected users are in the response array + for _, user := range users { + if !slices.ContainsFunc(resArr, func(value resp.Value) bool { + return value.String() == user + }) { + t.Errorf("could not find expected user \"%s\" in response array", user) + } + } + + // Check if all the users in the response array are in the expected users + for _, value := range resArr { + if !slices.ContainsFunc(users, func(user string) bool { + return value.String() == user + }) { + t.Errorf("could not find response user \"%s\" in expected users array", value.String()) + } + } + }) + + t.Run("Test_HandleSetUser", func(t *testing.T) { + port, err := internal.GetFreePort() + if err != nil { + t.Error(err) + return + } + + mockServer, err := setUpServer(port, false, "") + if err != nil { + t.Error(err) + return + } + + go func() { + mockServer.Start() + }() + + conn, err := internal.GetConnection("localhost", port) + if err != nil { + t.Error(err) + return + } + defer func() { + if conn != nil { + _ = conn.Close() + } + }() + + r := resp.NewConn(conn) + + t.Cleanup(func() { + mockServer.ShutDown() + }) + + tests := []struct { + name string + presetUser *echovault.User + cmd []resp.Value + wantRes string + wantErr string + wantUser map[string][]string + }{ + { + name: "1. Create new enabled user", + presetUser: nil, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("SETUSER"), + resp.StringValue("set_user_1"), + resp.StringValue("on"), + }, + wantRes: "OK", + wantErr: "", + wantUser: map[string][]string{ + "username": {"set_user_1"}, + "flags": {"on"}, + "categories": {"+@all"}, + "commands": {"+all"}, + "keys": {"%RW~*"}, + "channels": {"+&*"}, + }, + }, + { + name: "2. Create new disabled user", + presetUser: nil, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("SETUSER"), + resp.StringValue("set_user_2"), + resp.StringValue("off"), + }, + wantRes: "OK", + wantErr: "", + wantUser: map[string][]string{ + "username": {"set_user_2"}, + "flags": {"off"}, + "categories": {"+@all"}, + "commands": {"+all"}, + "keys": {"%RW~*"}, + "channels": {"+&*"}, + }, + }, + { + name: "3. Create new enabled user with both plaintext and SHA256 passwords", + presetUser: nil, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("SETUSER"), + resp.StringValue("set_user_3"), + resp.StringValue("on"), + resp.StringValue(">set_user_3_plaintext_password_1"), + resp.StringValue(">set_user_3_plaintext_password_2"), + resp.StringValue(fmt.Sprintf("#%s", generateSHA256Password("set_user_3_hash_password_1"))), + resp.StringValue(fmt.Sprintf("#%s", generateSHA256Password("set_user_3_hash_password_2"))), + }, + wantRes: "OK", + wantErr: "", + wantUser: map[string][]string{ + "username": {"set_user_3"}, + "flags": {"on"}, + "categories": {"+@all"}, + "commands": {"+all"}, + "keys": {"%RW~*"}, + "channels": {"+&*"}, + }, + }, + { + name: "4. Remove plaintext and SHA256 password from existing user", + presetUser: &echovault.User{ + Username: "set_user_4", + Enabled: true, + AddPlainPasswords: []string{"set_user_4_plaintext_password_1", "set_user_4_plaintext_password_2"}, + AddHashPasswords: []string{ + generateSHA256Password("set_user_4_hash_password_1"), + generateSHA256Password("set_user_4_hash_password_2"), + }, + }, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("SETUSER"), + resp.StringValue("set_user_4"), + resp.StringValue("on"), + resp.StringValue("password1"), + resp.StringValue(fmt.Sprintf("#%s", generateSHA256Password("password2"))), + }, + wantRes: "OK", + wantErr: "", + wantUser: map[string][]string{ + "username": {"set_user_16"}, + "flags": {"on", "nopass"}, + "categories": {"+@all"}, + "commands": {"+all"}, + "keys": {"%RW~*"}, + "channels": {"+&*"}, + }, + }, + { + name: "17. Delete all existing users passwords using 'nopass'", + presetUser: &echovault.User{ + Username: "set_user_17", + Enabled: true, + NoPassword: true, + AddPlainPasswords: []string{"password1"}, + AddHashPasswords: []string{generateSHA256Password("password2")}, + }, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("SETUSER"), + resp.StringValue("set_user_17"), + resp.StringValue("on"), + resp.StringValue("nopass"), + }, + wantRes: "OK", + wantErr: "", + wantUser: map[string][]string{ + "username": {"set_user_17"}, + "flags": {"on", "nopass"}, + "categories": {"+@all"}, + "commands": {"+all"}, + "keys": {"%RW~*"}, + "channels": {"+&*"}, + }, + }, + { + name: "18. Clear all of an existing user's passwords using 'resetpass'", + presetUser: &echovault.User{ + Username: "set_user_18", + Enabled: true, + NoPassword: true, + AddPlainPasswords: []string{"password1"}, + AddHashPasswords: []string{generateSHA256Password("password2")}, + }, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("SETUSER"), + resp.StringValue("set_user_18"), + resp.StringValue("on"), + resp.StringValue("nopass"), + }, + wantRes: "OK", + wantErr: "", + wantUser: map[string][]string{ + "username": {"set_user_18"}, + "flags": {"on", "nopass"}, + "categories": {"+@all"}, + "commands": {"+all"}, + "keys": {"%RW~*"}, + "channels": {"+&*"}, + }, + }, + { + name: "19. Clear all of an existing user's command privileges using 'nocommands'", + presetUser: &echovault.User{ + Username: "set_user_19", + Enabled: true, + IncludeCommands: []string{"acl|getuser", "acl|setuser", "acl|deluser"}, + ExcludeCommands: []string{"rewriteaof", "save"}, + }, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("SETUSER"), + resp.StringValue("set_user_19"), + resp.StringValue("on"), + resp.StringValue("nocommands"), + }, + wantRes: "OK", + wantErr: "", + wantUser: map[string][]string{ + "username": {"set_user_19"}, + "flags": {"on"}, + "categories": {"-@all"}, + "commands": {"-all"}, + "keys": {"%RW~*"}, + "channels": {"+&*"}, + }, + }, + { + name: "20. Clear all of an existing user's allowed keys using 'resetkeys'", + presetUser: &echovault.User{ + Username: "set_user_20", + Enabled: true, + IncludeWriteKeys: []string{"key1", "key2", "key3", "key4", "key5", "key6"}, + IncludeReadKeys: []string{"key1", "key2", "key3", "key7", "key8", "key9"}, + }, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("SETUSER"), + resp.StringValue("set_user_20"), + resp.StringValue("on"), + resp.StringValue("resetkeys"), + }, + wantRes: "OK", + wantErr: "", + wantUser: map[string][]string{ + "username": {"set_user_20"}, + "flags": {"on", "nokeys"}, + "categories": {"+@all"}, + "commands": {"+all"}, + "keys": {}, + "channels": {"+&*"}, + }, + }, + { + name: "21. Allow user to access all channels using 'resetchannels'", + presetUser: &echovault.User{ + Username: "set_user_21", + Enabled: true, + IncludeChannels: []string{"channel1", "channel2"}, + ExcludeChannels: []string{"channel3", "channel4"}, + }, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("SETUSER"), + resp.StringValue("set_user_21"), + resp.StringValue("resetchannels"), + }, + wantRes: "OK", + wantErr: "", + wantUser: map[string][]string{ + "username": {"set_user_21"}, + "flags": {"on"}, + "categories": {"+@all"}, + "commands": {"+all"}, + "keys": {"%RW~*"}, + "channels": {"-&*"}, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.presetUser != nil { + if _, err := mockServer.ACLSetUser(*test.presetUser); err != nil { + t.Error(err) + return + } + } + if err = r.WriteArray(test.cmd); err != nil { + t.Error(err) + } + v, _, err := r.ReadValue() + if err != nil { + t.Error(err) + } + if test.wantErr != "" { + if v.Error().Error() != test.wantErr { + t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, v.Error().Error()) + } + return + } + if v.String() != test.wantRes { + t.Errorf("expected response \"%s\", got \"%s\"", test.wantRes, v.String()) + } + if test.wantUser == nil { + return + } + + user, err := mockServer.ACLGetUser(test.wantUser["username"][0]) + if err != nil { + t.Error(err) + return + } + + if err = compareUsers(test.wantUser, user); err != nil { + t.Error(err) + return + } + }) + } + }) + + t.Run("Test_HandleGetUser", func(t *testing.T) { + port, err := internal.GetFreePort() + if err != nil { + t.Error(err) + return + } + + mockServer, err := setUpServer(port, false, "") + if err != nil { + t.Error(err) + return + } + go func() { + mockServer.Start() + }() + + t.Cleanup(func() { + mockServer.ShutDown() + }) + + conn, err := internal.GetConnection("localhost", port) + if err != nil { + t.Error(err) + return + } + defer func() { + if conn != nil { + _ = conn.Close() + } + }() + + r := resp.NewConn(conn) + + tests := []struct { + name string + presetUser *echovault.User + cmd []resp.Value + wantRes []resp.Value + wantErr string + }{ + { + name: "1. Get the user and all their details", + presetUser: &echovault.User{ + Username: "get_user_1", + Enabled: true, + NoPassword: false, + NoKeys: false, + AddPlainPasswords: []string{"get_user_password_1"}, + AddHashPasswords: []string{generateSHA256Password("get_user_password_2")}, + IncludeCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory}, + ExcludeCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory}, + IncludeCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, + ExcludeCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, + IncludeReadKeys: []string{"key1", "key2", "key3", "key4"}, + IncludeWriteKeys: []string{"key1", "key2", "key5", "key6"}, + IncludeChannels: []string{"channel1", "channel2"}, + ExcludeChannels: []string{"channel3", "channel4"}, + }, + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("GETUSER"), resp.StringValue("get_user_1")}, + wantRes: []resp.Value{ + resp.StringValue("username"), + resp.ArrayValue([]resp.Value{resp.StringValue("get_user_1")}), + resp.StringValue("flags"), + resp.ArrayValue([]resp.Value{ + resp.StringValue("on"), + }), + resp.StringValue("categories"), + resp.ArrayValue([]resp.Value{ + resp.StringValue(fmt.Sprintf("+@%s", constants.WriteCategory)), + resp.StringValue(fmt.Sprintf("+@%s", constants.ReadCategory)), + resp.StringValue(fmt.Sprintf("+@%s", constants.PubSubCategory)), + resp.StringValue(fmt.Sprintf("-@%s", constants.AdminCategory)), + resp.StringValue(fmt.Sprintf("-@%s", constants.ConnectionCategory)), + resp.StringValue(fmt.Sprintf("-@%s", constants.DangerousCategory)), + }), + resp.StringValue("commands"), + resp.ArrayValue([]resp.Value{ + resp.StringValue("+acl|setuser"), + resp.StringValue("+acl|getuser"), + resp.StringValue("+acl|deluser"), + resp.StringValue("-rewriteaof"), + resp.StringValue("-save"), + resp.StringValue("-acl|load"), + resp.StringValue("-acl|save"), + }), + resp.StringValue("keys"), + resp.ArrayValue([]resp.Value{ + // Keys here + resp.StringValue("%RW~key1"), + resp.StringValue("%RW~key2"), + resp.StringValue("%R~key3"), + resp.StringValue("%R~key4"), + resp.StringValue("%W~key5"), + resp.StringValue("%W~key6"), + }), + resp.StringValue("channels"), + resp.ArrayValue([]resp.Value{ + // Channels here + resp.StringValue("+&channel1"), + resp.StringValue("+&channel2"), + resp.StringValue("-&channel3"), + resp.StringValue("-&channel4"), + }), + }, + wantErr: "", + }, + { + name: "2. Return user not found error", + presetUser: nil, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("GETUSER"), + resp.StringValue("non_existent_user")}, + wantRes: nil, + wantErr: "Error user not found", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.presetUser != nil { + if _, err := mockServer.ACLSetUser(*test.presetUser); err != nil { + t.Error(err) + return + } + } + if err = r.WriteArray(test.cmd); err != nil { + t.Error(err) + } + v, _, err := r.ReadValue() + if err != nil { + t.Error(err) + } + if test.wantErr != "" { + if v.Error().Error() != test.wantErr { + t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, v.Error().Error()) + } + return + } + resArr := v.Array() + for i := 0; i < len(resArr); i++ { + if slices.Contains([]string{"username", "flags", "categories", "commands", "keys", "channels"}, resArr[i].String()) { + // String item + if resArr[i].String() != test.wantRes[i].String() { + t.Errorf("expected response component %+v, got %+v", test.wantRes[i], resArr[i]) + } + } else { + // Array item + var expected []string + for _, item := range test.wantRes[i].Array() { + expected = append(expected, item.String()) + } + + var res []string + for _, item := range resArr[i].Array() { + res = append(res, item.String()) + } + + if err = compareSlices(res, expected); err != nil { + t.Error(err) + } + } + } + }) + } + }) + + t.Run("Test_HandleDelUser", func(t *testing.T) { + port, err := internal.GetFreePort() + if err != nil { + t.Error(err) + return + } + + mockServer, err := setUpServer(port, false, "") + if err != nil { + t.Error(err) + return + } + + go func() { + mockServer.Start() + }() + + t.Cleanup(func() { + mockServer.ShutDown() + }) + + conn, err := internal.GetConnection("localhost", port) + if err != nil { + t.Error(err) + return + } + defer func() { + if conn != nil { + _ = conn.Close() + } + }() + r := resp.NewConn(conn) + + tests := []struct { + name string + presetUser *echovault.User + cmd []resp.Value + wantRes string + wantErr string + }{ + { + name: "1. Delete existing user while skipping default user and non-existent user", + presetUser: &echovault.User{ + Username: "user_to_delete", + Enabled: true, + }, + cmd: []resp.Value{ + resp.StringValue("ACL"), + resp.StringValue("DELUSER"), + resp.StringValue("default"), + resp.StringValue("user_to_delete"), + resp.StringValue("non_existent_user"), + }, + wantRes: "OK", + wantErr: "", + }, + { + name: "2. Command too short", + presetUser: nil, + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("DELUSER")}, + wantRes: "", + wantErr: fmt.Sprintf("Error %s", constants.WrongArgsResponse), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.presetUser != nil { + if _, err := mockServer.ACLSetUser(*test.presetUser); err != nil { + t.Error(err) + return + } + } + if err = r.WriteArray(test.cmd); err != nil { + t.Error(err) + } + v, _, err := r.ReadValue() + if err != nil { + t.Error(err) + } + if test.wantErr != "" { + if v.Error().Error() != test.wantErr { + t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, v.Error().Error()) + } + return + } + + usernames, err := mockServer.ACLUsers() + if err != nil { + t.Error(err) + return + } + + // Check that default user still exists in the list of users + if !slices.Contains(usernames, "default") { + t.Error("could not find user with username \"default\" in the ACL after deleting user") + return + } + + // Check that the deleted user is no longer in the list + if slices.Contains(usernames, "user_to_delete") { + t.Error("deleted user found in the ACL") + return + } + }) + } + }) + + t.Run("Test_HandleWhoAmI", func(t *testing.T) { + conn, err := internal.GetConnection("localhost", port) + if err != nil { + t.Error(err) + return + } + defer func() { + if conn != nil { + _ = conn.Close() + } + }() + + r := resp.NewConn(conn) + + tests := []struct { + name string + username string + password string + wantRes string + }{ + { + name: "1. With default user", + username: "default", + password: "password1", + wantRes: "default", + }, + { + name: "2. With user authenticated by plaintext password", + username: "with_password_user", + password: "password2", + wantRes: "with_password_user", + }, + { + name: "3. With user authenticated by SHA256 password", + username: "with_password_user", + password: "password3", + wantRes: "with_password_user", + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + // Authenticate + if err = r.WriteArray([]resp.Value{ + resp.StringValue("AUTH"), + resp.StringValue(test.username), + resp.StringValue(test.password), + }); err != nil { + t.Error(err) + } + v, _, err := r.ReadValue() + if err != nil { + t.Error(err) + } + if v.String() != "OK" { + t.Errorf("expected response for auth with %s:%s to be \"OK\", got %s", test.username, test.password, v.String()) + } + // Check whoami response value + if err = r.WriteArray([]resp.Value{resp.StringValue("ACL"), resp.StringValue("WHOAMI")}); err != nil { + t.Error(err) + } + v, _, err = r.ReadValue() + if err != nil { + t.Error(err) + } + if v.String() != test.wantRes { + t.Errorf("expected whoami response to be \"%s\", got \"%s\"", test.wantRes, v.String()) + } + }) + } + }) + + t.Run("Test_HandleList", func(t *testing.T) { + port, err := internal.GetFreePort() + if err != nil { + t.Error(err) + return + } + + mockServer, err := setUpServer(port, false, "") + if err != nil { + t.Error(err) + return + } + go func() { + mockServer.Start() + }() + + t.Cleanup(func() { + mockServer.ShutDown() + }) + + conn, err := internal.GetConnection("localhost", port) + if err != nil { + t.Error(err) + return + } + defer func() { + if conn != nil { + _ = conn.Close() + } + }() + + r := resp.NewConn(conn) + + tests := []struct { + name string + presetUsers []*echovault.User + cmd []resp.Value + wantRes []string + wantErr string + }{ + { + name: "1. Get the user and all their details", + presetUsers: []*echovault.User{ + { + Username: "list_user_1", + Enabled: true, + NoPassword: false, + NoKeys: false, + AddPlainPasswords: []string{"list_user_password_1"}, + AddHashPasswords: []string{generateSHA256Password("list_user_password_2")}, + IncludeCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory}, + ExcludeCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory}, + IncludeCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, + ExcludeCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, + IncludeReadKeys: []string{"key1", "key2", "key3", "key4"}, + IncludeWriteKeys: []string{"key1", "key2", "key5", "key6"}, + IncludeChannels: []string{"channel1", "channel2"}, + ExcludeChannels: []string{"channel3", "channel4"}, + }, + { + Username: "list_user_2", + Enabled: true, + NoPassword: true, + NoKeys: true, + IncludeCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory}, + ExcludeCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory}, + IncludeCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, + ExcludeCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, + IncludeReadKeys: []string{}, + IncludeWriteKeys: []string{}, + IncludeChannels: []string{"channel1", "channel2"}, + ExcludeChannels: []string{"channel3", "channel4"}, + }, + { + Username: "list_user_3", + Enabled: true, + NoPassword: false, + NoKeys: false, + AddPlainPasswords: []string{"list_user_password_3"}, + AddHashPasswords: []string{generateSHA256Password("list_user_password_4")}, + IncludeCategories: []string{constants.WriteCategory, constants.ReadCategory, constants.PubSubCategory}, + ExcludeCategories: []string{constants.AdminCategory, constants.ConnectionCategory, constants.DangerousCategory}, + IncludeCommands: []string{"acl|setuser", "acl|getuser", "acl|deluser"}, + ExcludeCommands: []string{"rewriteaof", "save", "acl|load", "acl|save"}, + IncludeReadKeys: []string{"key1", "key2", "key3", "key4"}, + IncludeWriteKeys: []string{"key1", "key2", "key5", "key6"}, + IncludeChannels: []string{"channel1", "channel2"}, + ExcludeChannels: []string{"channel3", "channel4"}, + }, + }, + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("LIST")}, + wantRes: []string{ + "default on +@all +all %RW~* +&*", + fmt.Sprintf("with_password_user on >password2 #%s +@all +all %s~* +&*", + generateSHA256Password("password3"), "%RW"), + "no_password_user on nopass +@all +all %RW~* +&*", + "disabled_user off >password5 +@all +all %RW~* +&*", + fmt.Sprintf(`list_user_1 on >list_user_password_1 #%s +@write +@read +@pubsub -@admin -@connection -@dangerous +acl|setuser +acl|getuser +acl|deluser -rewriteaof -save -acl|load -acl|save %s +&channel1 +&channel2 -&channel3 -&channel4`, generateSHA256Password("list_user_password_2"), "%RW~key1 %RW~key2 %R~key3 %R~key4"), + fmt.Sprintf(`list_user_2 on nopass nokeys +@write +@read +@pubsub -@admin -@connection -@dangerous +acl|setuser +acl|getuser +acl|deluser -rewriteaof -save -acl|load -acl|save +&channel1 +&channel2 -&channel3 -&channel4`), + fmt.Sprintf(`list_user_3 on >list_user_password_3 #%s +@write +@read +@pubsub -@admin -@connection -@dangerous +acl|setuser +acl|getuser +acl|deluser -rewriteaof -save -acl|load -acl|save %s +&channel1 +&channel2 -&channel3 -&channel4`, generateSHA256Password("list_user_password_4"), "%RW~key1 %RW~key2 %R~key3 %R~key4"), + }, + wantErr: "", + }, + { + name: "2. Command too long", + cmd: []resp.Value{resp.StringValue("ACL"), resp.StringValue("LIST"), resp.StringValue("USERNAME")}, + wantRes: nil, + wantErr: constants.WrongArgsResponse, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if test.presetUsers != nil { + for _, user := range test.presetUsers { + if _, err := mockServer.ACLSetUser(*user); err != nil { + t.Error(err) + return + } + } + } + + if err = r.WriteArray(test.cmd); err != nil { + t.Error(err) + return + } + v, _, err := r.ReadValue() + if err != nil { + t.Error(err) + return + } + if test.wantErr != "" { + if !strings.Contains(v.Error().Error(), test.wantErr) { + t.Errorf("expected error response \"%s\", got \"%s\"", test.wantErr, v.Error().Error()) + } + return + } + resArr := v.Array() + if len(resArr) != len(test.wantRes) { + t.Errorf("expected response of lenght %d, got lenght %d", len(test.wantRes), len(resArr)) + return + } + + var resStr []string + for i := 0; i < len(resArr); i++ { + resStr = strings.Split(resArr[i].String(), " ") + if !slices.ContainsFunc(test.wantRes, func(s string) bool { + expectedUserSlice := strings.Split(s, " ") + return compareSlices(resStr, expectedUserSlice) == nil + }) { + t.Errorf("could not find the following user in expected slice: %+v", resStr) + return + } + clear(resStr) + } + }) + } + }) +} diff --git a/internal/modules/acl/user.go b/internal/modules/acl/user.go index 948de1f..601c918 100644 --- a/internal/modules/acl/user.go +++ b/internal/modules/acl/user.go @@ -241,8 +241,8 @@ func (user *User) UpdateUser(cmd []string) error { user.IncludedCategories = []string{} user.ExcludedCategories = []string{"*"} } - // If resetkeys is provided, reset all keys that the user can access - if strings.EqualFold(str, "resetkeys") { + // If resetkeys or nokeys is provided, reset all keys that the user can access. + if slices.Contains([]string{"resetkeys", "nokeys"}, str) { user.IncludedReadKeys = []string{} user.IncludedWriteKeys = []string{} user.NoKeys = true