PageRenderTime 54ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/test/dsl_base_test.rb

https://github.com/jej/acl9
Ruby | 756 lines | 624 code | 131 blank | 1 comment | 9 complexity | 667ece31888fde54ea62ccc964897ea2 MD5 | raw file
  1. require 'ostruct'
  2. require 'test_helper'
  3. require File.join(File.dirname(__FILE__), '..', 'lib', 'acl9', 'controller_extensions', 'dsl_base')
  4. class FakeUser
  5. def initialize
  6. @roles = {}
  7. end
  8. def has_role?(role, object = nil)
  9. @roles.include?([role.to_s, object])
  10. end
  11. def <<(role)
  12. role = [role] unless role.is_a? Array
  13. role << nil if role.size == 1
  14. raise unless role[0]
  15. role[0] = role[0].to_s
  16. @roles[role] = true
  17. end
  18. end
  19. class DslTester < Acl9::Dsl::Base
  20. def initialize
  21. super
  22. @_subject = nil
  23. @_objects = {}
  24. @_current_action = nil
  25. end
  26. def permit(user, *args)
  27. check_allowance(user, *args).should == true
  28. self
  29. end
  30. def forbid(user, *args)
  31. check_allowance(user, *args).should == false
  32. self
  33. end
  34. def show_code
  35. puts "\n", allowance_expression
  36. self
  37. end
  38. protected
  39. def check_allowance(subject, *args)
  40. @_subject = subject
  41. @_current_action = (args[0] || 'index').to_s
  42. @_objects = args.last.is_a?(Hash) ? args.last : {}
  43. @_callable = @_objects.delete(:call)
  44. instance_eval(allowance_expression)
  45. end
  46. def _subject_ref
  47. "@_subject"
  48. end
  49. def _object_ref(object)
  50. "@_objects[:#{object}]"
  51. end
  52. def _action_ref
  53. "@_current_action"
  54. end
  55. def _method_ref(method)
  56. "@_callable.send(:#{method})"
  57. end
  58. end
  59. #describe Acl9::Dsl::Base do
  60. class DslBaseTest < Test::Unit::TestCase
  61. class ThatFoo; end
  62. class ThatBar; end
  63. def arg_err(&block)
  64. lambda do
  65. acl(&block)
  66. end.should raise_error(ArgumentError)
  67. end
  68. def acl(&block)
  69. tester = DslTester.new
  70. tester.acl_block!(&block)
  71. tester
  72. end
  73. def permit_some(tester, user, actions, vars = {})
  74. actions.each { |act| tester.permit(user, act, vars) }
  75. (@all_actions - actions).each { |act| tester.forbid(user, act, vars) }
  76. end
  77. before do
  78. @user = FakeUser.new
  79. @user2 = FakeUser.new
  80. @user3 = FakeUser.new
  81. @foo = ThatFoo.new
  82. @foo2 = ThatFoo.new
  83. @foo3 = ThatFoo.new
  84. end
  85. describe "default" do
  86. it "should set default action to deny if none specified" do
  87. acl do end.default_action.should == :deny
  88. end
  89. it "should set default action to allow" do
  90. acl do
  91. default :allow
  92. end.default_action.should == :allow
  93. end
  94. it "should set default action to deny" do
  95. acl do
  96. default :deny
  97. end.default_action.should == :deny
  98. end
  99. it "should raise ArgumentError with unknown default_action" do
  100. arg_err do
  101. default 123
  102. end
  103. end
  104. it "should raise ArgumentError when default is called more than once" do
  105. arg_err do
  106. default :deny
  107. default :deny
  108. end
  109. end
  110. end
  111. describe "empty blocks" do
  112. it "should deny everyone with default deny" do
  113. acl do
  114. end.forbid(nil).forbid(@user)
  115. end
  116. it "should allow everyone with default allow" do
  117. acl do
  118. default :allow
  119. end.permit(nil).permit(@user)
  120. end
  121. end
  122. describe "empty" do
  123. it "allow should raise an ArgumentError" do
  124. arg_err { allow }
  125. end
  126. it "deny should raise an ArgumentError" do
  127. arg_err { deny }
  128. end
  129. end
  130. describe "anonymous" do
  131. it "'allow nil' should allow anonymous, but not logged in" do
  132. acl do
  133. allow nil
  134. end.permit(nil).forbid(@user)
  135. end
  136. it "'allow anonymous' should allow anonymous, but not logged in" do
  137. acl do
  138. allow anonymous
  139. end.permit(nil).forbid(@user)
  140. end
  141. it "'deny nil' should deny anonymous, but not logged in" do
  142. acl do
  143. default :allow
  144. deny nil
  145. end.forbid(nil).permit(@user)
  146. end
  147. it "'deny anonymous' should deny anonymous, but not logged in" do
  148. acl do
  149. default :allow
  150. deny anonymous
  151. end.forbid(nil).permit(@user)
  152. end
  153. end
  154. describe "all" do
  155. it "'allow all' should allow all" do
  156. acl do
  157. allow all
  158. end.permit(nil).permit(@user)
  159. end
  160. it "'deny all' should deny all" do
  161. acl do
  162. default :allow
  163. deny all
  164. end.forbid(nil).forbid(@user)
  165. end
  166. end
  167. describe "default :allow" do
  168. it "should allow when neither allow nor deny conditions are matched" do
  169. acl do
  170. default :allow
  171. allow :blah
  172. deny :bzz
  173. end.permit(nil).permit(@user)
  174. end
  175. it "should deny when deny is matched, but allow is not" do
  176. acl do
  177. default :allow
  178. deny all
  179. allow :blah
  180. end.forbid(nil).forbid(@user)
  181. end
  182. it "should allow when allow is matched, but deny is not" do
  183. @user << :cool
  184. acl do
  185. default :allow
  186. deny nil
  187. allow :cool
  188. end.permit(@user)
  189. end
  190. it "should allow both allow and deny conditions are matched" do
  191. @user << :cool
  192. acl do
  193. default :allow
  194. deny :cool
  195. allow :cool
  196. end.permit(@user)
  197. acl do
  198. default :allow
  199. deny all
  200. allow all
  201. end.permit(@user).permit(nil).permit(@user2)
  202. end
  203. end
  204. describe "logged_in" do
  205. it "'allow logged_in' should allow logged in, but not anonymous" do
  206. acl do
  207. allow logged_in
  208. end.forbid(nil).permit(@user)
  209. end
  210. it "'allow logged_in' should deny logged in, but not anonymous" do
  211. acl do
  212. default :allow
  213. deny logged_in
  214. end.permit(nil).forbid(@user)
  215. end
  216. end
  217. describe "default :deny" do
  218. it "should deny when neither allow nor deny conditions are matched" do
  219. acl do
  220. default :deny
  221. allow :blah
  222. deny :bzz
  223. end.forbid(nil).forbid(@user)
  224. end
  225. it "should deny when deny is matched, but allow is not" do
  226. acl do
  227. default :deny
  228. deny all
  229. allow :blah
  230. end.forbid(nil).forbid(@user)
  231. end
  232. it "should allow when allow is matched, but deny is not" do
  233. @user << :cool
  234. acl do
  235. default :deny
  236. deny nil
  237. allow :cool
  238. end.permit(@user)
  239. end
  240. it "should deny both allow and deny conditions are matched" do
  241. @user << :cool
  242. acl do
  243. default :deny
  244. deny :cool
  245. allow :cool
  246. end.forbid(@user)
  247. acl do
  248. default :deny
  249. deny all
  250. allow all
  251. end.forbid(@user).forbid(nil).forbid(@user2)
  252. end
  253. end
  254. describe "global roles" do
  255. it "#allow with role" do
  256. @user << :admin
  257. acl { allow :admin }.permit(@user).forbid(nil).forbid(@user2)
  258. end
  259. it "#allow with plural role name" do
  260. @user << :mouse
  261. acl do
  262. allow :mice
  263. end.permit(@user).forbid(nil).forbid(@user2)
  264. end
  265. it "#allow with several roles" do
  266. @user << :admin
  267. @user << :cool
  268. @user2 << :cool
  269. @user3 << :super
  270. acl do
  271. allow :admin
  272. allow :cool
  273. end.permit(@user).permit(@user2).forbid(nil).forbid(@user3)
  274. end
  275. it "#deny with role" do
  276. @user << :foo
  277. acl { default :allow; deny :foo }.forbid(@user).permit(nil).permit(@user2)
  278. end
  279. it "#deny with plural role name" do
  280. @user << :mouse
  281. acl do
  282. default :allow
  283. deny :mice
  284. end.forbid(@user).permit(nil).permit(@user2)
  285. end
  286. it "#deny with several roles" do
  287. @user << :admin
  288. @user << :cool
  289. @user2 << :cool
  290. @user3 << :super
  291. acl do
  292. default :allow
  293. deny :admin
  294. deny :cool
  295. end.forbid(@user).forbid(@user2).permit(nil).permit(@user3)
  296. end
  297. end
  298. describe "prepositions" do
  299. [:of, :for, :in, :on, :at, :by].each do |prep|
  300. it "#allow with object role (:#{prep}) should check controller's ivar" do
  301. @user << [:manager, @foo]
  302. acl do
  303. allow :manager, prep => :foo
  304. end.
  305. permit(@user, :foo => @foo).
  306. forbid(@user, :foo => @foo2).
  307. forbid(@user, :foo => ThatFoo).
  308. forbid(nil, :foo => @foo).
  309. forbid(@user2, :foo => @foo)
  310. end
  311. it "#allow with invalid value for preposition :#{prep} should raise an ArgumentError" do
  312. arg_err do
  313. allow :hom, :by => 1
  314. end
  315. end
  316. end
  317. it "#allow with a class role should verify this role against a class" do
  318. @user << [:owner, ThatFoo]
  319. acl do
  320. allow :owner, :of => ThatFoo
  321. end.permit(@user).forbid(nil).forbid(@user2)
  322. end
  323. [:of, :for, :in, :on, :at, :by].each do |prep|
  324. it "#deny with object role (:#{prep}) should check controller's ivar" do
  325. @user << [:bastard, @foo]
  326. acl do
  327. default :allow
  328. deny :bastard, prep => :foo
  329. end.
  330. forbid(@user, :foo => @foo).
  331. permit(@user, :foo => @foo2).
  332. permit(@user, :foo => ThatFoo).
  333. permit(nil, :foo => @foo).
  334. permit(@user2, :foo => @foo)
  335. end
  336. it "#deny with invalid value for preposition :#{prep} should raise an ArgumentError" do
  337. arg_err do
  338. deny :her, :for => "him"
  339. end
  340. end
  341. end
  342. it "#deny with a class role should verify this role against a class" do
  343. @user << [:ignorant, ThatFoo]
  344. acl do
  345. default :allow
  346. deny :ignorant, :of => ThatFoo
  347. end.forbid(@user).permit(nil).permit(@user2)
  348. end
  349. it "#allow with several prepositions should raise an ArgumentError" do
  350. arg_err do
  351. allow :some, :by => :one, :for => :another
  352. end
  353. end
  354. it "#deny with several prepositions should raise an ArgumentError" do
  355. arg_err do
  356. deny :some, :in => :here, :on => :today
  357. end
  358. end
  359. end
  360. describe ":to and :except" do
  361. it "should raise an ArgumentError when both :to and :except are specified" do
  362. arg_err do
  363. allow all, :to => :index, :except => ['show', 'edit']
  364. end
  365. end
  366. describe "" do
  367. after do
  368. %w(index show).each { |act| @list.permit(nil, act) }
  369. %w(edit update delete destroy).each { |act| @list.forbid(nil, act) }
  370. %w(index show edit update).each { |act| @list.permit(@user, act) }
  371. %w(delete destroy).each { |act| @list.forbid(@user, act) }
  372. %w(index show edit update delete destroy).each { |act| @list.permit(@user2, act) }
  373. end
  374. it ":to should limit rule scope to specified actions" do
  375. @user << :manager
  376. @user2 << :trusted
  377. @list = acl do
  378. allow all, :to => [:index, :show]
  379. allow 'manager', :to => :edit
  380. allow 'manager', :to => 'update'
  381. allow 'trusted', :to => %w(edit update delete destroy)
  382. end
  383. end
  384. it ":except should limit rule scope to all actions except specified" do
  385. @user << :manager
  386. @user2 << :trusted
  387. @list = acl do
  388. allow all, :except => %w(edit update delete destroy)
  389. allow 'manager', :except => %w(delete destroy)
  390. allow 'trusted'
  391. end
  392. end
  393. end
  394. end
  395. describe "conditions" do
  396. [:if, :unless].each do |cond|
  397. it "should raise ArgumentError when #{cond} is not a Symbol" do
  398. arg_err do
  399. allow nil, cond => 123
  400. end
  401. end
  402. end
  403. it "allow ... :if" do
  404. acl do
  405. allow nil, :if => :meth
  406. end.
  407. permit(nil, :call => OpenStruct.new(:meth => true)).
  408. forbid(nil, :call => OpenStruct.new(:meth => false))
  409. end
  410. it "allow ... :unless" do
  411. acl do
  412. allow nil, :unless => :meth
  413. end.
  414. permit(nil, :call => OpenStruct.new(:meth => false)).
  415. forbid(nil, :call => OpenStruct.new(:meth => true))
  416. end
  417. it "deny ... :if" do
  418. acl do
  419. default :allow
  420. deny nil, :if => :meth
  421. end.
  422. permit(nil, :call => OpenStruct.new(:meth => false)).
  423. forbid(nil, :call => OpenStruct.new(:meth => true))
  424. end
  425. it "deny ... :unless" do
  426. acl do
  427. default :allow
  428. deny nil, :unless => :meth
  429. end.
  430. permit(nil, :call => OpenStruct.new(:meth => true)).
  431. forbid(nil, :call => OpenStruct.new(:meth => false))
  432. end
  433. end
  434. describe "several roles as arguments" do
  435. it "#allow should be able to receive a role list (global roles)" do
  436. @user << :bzz
  437. @user2 << :whoa
  438. acl do
  439. allow :bzz, :whoa
  440. end.permit(@user).permit(@user2).forbid(nil).forbid(@user3)
  441. end
  442. it "#allow should be able to receive a role list (object roles)" do
  443. @user << [:maker, @foo]
  444. @user2 << [:faker, @foo2]
  445. acl do
  446. allow :maker, :faker, :of => :foo
  447. end.
  448. permit(@user, :foo => @foo).
  449. forbid(@user, :foo => @foo2).
  450. permit(@user2, :foo => @foo2).
  451. forbid(@user2, :foo => @foo).
  452. forbid(@user3, :foo => @foo).
  453. forbid(@user3, :foo => @foo2).
  454. forbid(nil)
  455. end
  456. it "#allow should be able to receive a role list (class roles)" do
  457. @user << [:frooble, ThatFoo]
  458. @user2 << [:oombigle, ThatFoo]
  459. @user3 << :frooble
  460. acl do
  461. allow :frooble, :oombigle, :by => ThatFoo
  462. end.
  463. permit(@user).
  464. permit(@user2).
  465. forbid(@user3).
  466. forbid(nil)
  467. end
  468. it "#deny should be able to receive a role list (global roles)" do
  469. @user << :bzz
  470. @user2 << :whoa
  471. acl do
  472. default :allow
  473. deny :bzz, :whoa
  474. end.forbid(@user).forbid(@user2).permit(nil).permit(@user3)
  475. end
  476. it "#deny should be able to receive a role list (object roles)" do
  477. @user << [:maker, @foo]
  478. @user2 << [:faker, @foo2]
  479. @user3 = FakeUser.new
  480. acl do
  481. default :allow
  482. deny :maker, :faker, :of => :foo
  483. end.
  484. forbid(@user, :foo => @foo).
  485. permit(@user, :foo => @foo2).
  486. forbid(@user2, :foo => @foo2).
  487. permit(@user2, :foo => @foo).
  488. permit(@user3, :foo => @foo).
  489. permit(@user3, :foo => @foo2).
  490. permit(nil)
  491. end
  492. it "#deny should be able to receive a role list (class roles)" do
  493. @user << [:frooble, ThatFoo]
  494. @user2 << [:oombigle, ThatFoo]
  495. @user3 << :frooble
  496. acl do
  497. default :allow
  498. deny :frooble, :oombigle, :by => ThatFoo
  499. end.
  500. forbid(@user).
  501. forbid(@user2).
  502. permit(@user3).
  503. permit(nil)
  504. end
  505. it "should also respect :to and :except" do
  506. class Moo; end
  507. @user << :foo
  508. @user2 << [:joo, @foo]
  509. @user3 << [:qoo, Moo]
  510. acl do
  511. allow :foo, :boo, :to => [:index, :show]
  512. allow :zoo, :joo, :by => :foo, :to => [:edit, :update]
  513. allow :qoo, :woo, :of => Moo
  514. deny :qoo, :woo, :of => Moo, :except => [:delete, :destroy]
  515. end.
  516. permit(@user, 'index').
  517. permit(@user, 'show').
  518. forbid(@user, 'edit').
  519. permit(@user2, 'edit', :foo => @foo).
  520. permit(@user2, 'update', :foo => @foo).
  521. forbid(@user2, 'show', :foo => @foo).
  522. forbid(@user2, 'show').
  523. permit(@user3, 'delete').
  524. permit(@user3, 'destroy').
  525. forbid(@user3, 'edit').
  526. forbid(@user3, 'show')
  527. end
  528. end
  529. describe "actions block" do
  530. it "should raise an ArgumentError when actions has no block" do
  531. arg_err do
  532. actions :foo, :bar
  533. end
  534. end
  535. it "should raise an ArgumentError when actions has no arguments" do
  536. arg_err do
  537. actions do end
  538. end
  539. end
  540. it "should raise an ArgumentError when actions is called inside actions block" do
  541. arg_err do
  542. actions :foo, :bar do
  543. actions :foo, :bar do
  544. end
  545. end
  546. end
  547. end
  548. it "should raise an ArgumentError when default is called inside actions block" do
  549. arg_err do
  550. actions :foo, :bar do
  551. default :allow
  552. end
  553. end
  554. end
  555. [:to, :except].each do |opt|
  556. it "should raise an ArgumentError when allow is called with #{opt} option" do
  557. arg_err do
  558. actions :foo do
  559. allow all, opt => :bar
  560. end
  561. end
  562. end
  563. it "should raise an ArgumentError when deny is called with #{opt} option" do
  564. arg_err do
  565. actions :foo do
  566. deny all, opt => :bar
  567. end
  568. end
  569. end
  570. end
  571. it "empty actions block should do nothing" do
  572. acl do
  573. actions :foo do
  574. end
  575. allow all
  576. end.permit(nil).permit(nil, :foo)
  577. end
  578. it "#allow should limit its scope to specified actions" do
  579. @user << :bee
  580. acl do
  581. actions :edit do
  582. allow :bee
  583. end
  584. end.
  585. permit(@user, :edit).
  586. forbid(@user, :update)
  587. end
  588. it "#deny should limit its scope to specified actions" do
  589. @user << :bee
  590. acl do
  591. default :allow
  592. actions :edit do
  593. deny :bee
  594. end
  595. end.
  596. forbid(@user, :edit).
  597. permit(@user, :update)
  598. end
  599. it "#allow and #deny should work together inside actions block" do
  600. @foo = ThatFoo.new
  601. @user << [:owner, @foo]
  602. @user2 << :hacker
  603. @user2 << :the_destroyer
  604. @user3 << [:owner, @foo]
  605. @user3 << :hacker
  606. list = acl do
  607. actions :show, :index do
  608. allow all
  609. end
  610. actions :edit, :update do
  611. allow :owner, :of => :object
  612. deny :hacker
  613. end
  614. actions :delete, :destroy do
  615. allow :owner, :of => :object
  616. allow :the_destroyer
  617. end
  618. end
  619. @all_actions = %w(show index edit update delete destroy)
  620. permit_some(list, @user, @all_actions, :object => @foo)
  621. permit_some(list, @user2, %w(show index delete destroy))
  622. permit_some(list, @user3, %w(show index delete destroy), :object => @foo)
  623. end
  624. end
  625. end