token_spec.rb 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. require 'rails_helper'
  2. RSpec.describe Token, type: :model do
  3. subject(:token) { create(:password_reset_token) }
  4. describe '.check' do
  5. context 'with name and action matching existing token' do
  6. it 'returns the token’s user' do
  7. expect(described_class.check(action: token.action, name: token.name)).to eq(token.user)
  8. end
  9. end
  10. context 'with invalid name' do
  11. it 'returns nil' do
  12. expect(described_class.check(action: token.action, name: '1NV4L1D')).to be(nil)
  13. end
  14. end
  15. context 'with invalid action' do
  16. it 'returns nil' do
  17. expect(described_class.check(action: 'PasswordReset_NotExisting', name: token.name)).to be(nil)
  18. end
  19. end
  20. describe 'persistence handling' do
  21. context 'for persistent token' do
  22. subject(:token) { create(:ical_token, persistent: true, created_at: created_at) }
  23. context 'at any time' do
  24. let(:created_at) { 1.month.ago }
  25. it 'returns the token’s user' do
  26. expect(described_class.check(action: token.action, name: token.name)).to eq(token.user)
  27. end
  28. it 'does not delete the token' do
  29. token # create token
  30. expect { described_class.check(action: token.action, name: token.name) }
  31. .not_to change(described_class, :count)
  32. end
  33. end
  34. end
  35. context 'for non-persistent token' do
  36. subject(:token) { create(:password_reset_token, persistent: false, created_at: created_at) }
  37. context 'less than one day after creation' do
  38. let(:created_at) { 1.day.ago + 5 }
  39. it 'returns the token’s user' do
  40. expect(described_class.check(action: token.action, name: token.name)).to eq(token.user)
  41. end
  42. it 'does not delete the token' do
  43. token # create token
  44. expect { described_class.check(action: token.action, name: token.name) }
  45. .not_to change(described_class, :count)
  46. end
  47. end
  48. context 'at least one day after creation' do
  49. let(:created_at) { 1.day.ago }
  50. it 'returns nil' do
  51. expect(described_class.check(action: token.action, name: token.name)).to be(nil)
  52. end
  53. it 'deletes the token' do
  54. token # create token
  55. expect { described_class.check(action: token.action, name: token.name) }
  56. .to change(described_class, :count).by(-1)
  57. end
  58. end
  59. end
  60. end
  61. describe 'permission matching' do
  62. subject(:token) { create(:api_token, user: agent, preferences: preferences) }
  63. let(:agent) { create(:agent) }
  64. let(:preferences) { { permission: %w[admin ticket.agent] } } # agent has no access to admin.*
  65. context 'with a permission shared by both token.user and token.preferences' do
  66. it 'returns token.user' do
  67. expect(described_class.check(action: token.action, name: token.name, permission: 'ticket.agent')).to eq(agent)
  68. end
  69. end
  70. context 'with the child of a permission shared by both token.user and token.preferences' do
  71. it 'returns token.user' do
  72. expect(described_class.check(action: token.action, name: token.name, permission: 'ticket.agent.foo')).to eq(agent)
  73. end
  74. end
  75. context 'with the parent of a permission shared by both token.user and token.preferences' do
  76. it 'returns nil' do
  77. expect(described_class.check(action: token.action, name: token.name, permission: 'ticket')).to be(nil)
  78. end
  79. end
  80. context 'with a permission in token.preferences, but not on token.user' do
  81. it 'returns nil' do
  82. expect(described_class.check(action: token.action, name: token.name, permission: 'admin')).to be(nil)
  83. end
  84. end
  85. context 'with a permission not in token.preferences, but on token.user' do
  86. it 'returns nil' do
  87. expect(described_class.check(action: token.action, name: token.name, permission: 'cti.agent')).to be(nil)
  88. end
  89. end
  90. context 'with non-existent permission' do
  91. it 'returns nil' do
  92. expect(described_class.check(action: token.action, name: token.name, permission: 'foo')).to be(nil)
  93. end
  94. end
  95. context 'with multiple permissions, where at least one is shared by both token.user and token.preferences' do
  96. it 'returns token.user' do
  97. expect(described_class.check(action: token.action, name: token.name, permission: %w[foo ticket.agent])).to eq(agent)
  98. end
  99. end
  100. end
  101. end
  102. describe '#permissions?' do
  103. subject(:token) do
  104. create(:token, user: user, preferences: { permission: [permission_name] })
  105. end
  106. let(:user) { create(:user, roles: [role]) }
  107. let(:role) { create(:role, permissions: [permission]) }
  108. let(:permission) { create(:permission, name: permission_name) }
  109. context 'with privileges for a root permission (e.g., "foo", not "foo.bar")' do
  110. let(:permission_name) { 'foo' }
  111. context 'when given that exact permission' do
  112. it 'returns true' do
  113. expect(token.permissions?('foo')).to be(true)
  114. end
  115. end
  116. context 'when given a sub-permission (i.e., child permission)' do
  117. let(:subpermission) { create(:permission, name: 'foo.bar') }
  118. context 'that exists' do
  119. before { subpermission }
  120. it 'returns true' do
  121. expect(token.permissions?('foo.bar')).to be(true)
  122. end
  123. end
  124. context 'that is inactive' do
  125. before { subpermission.update(active: false) }
  126. it 'returns false' do
  127. expect(token.permissions?('foo.bar')).to be(false)
  128. end
  129. end
  130. context 'that does not exist' do
  131. it 'returns true' do
  132. expect(token.permissions?('foo.bar')).to be(true)
  133. end
  134. end
  135. end
  136. context 'when given a glob' do
  137. context 'matching that permission' do
  138. it 'returns true' do
  139. expect(token.permissions?('foo.*')).to be(true)
  140. end
  141. end
  142. context 'NOT matching that permission' do
  143. it 'returns false' do
  144. expect(token.permissions?('bar.*')).to be(false)
  145. end
  146. end
  147. end
  148. end
  149. context 'with privileges for a sub-permission (e.g., "foo.bar", not "foo")' do
  150. let(:permission_name) { 'foo.bar' }
  151. context 'when given that exact sub-permission' do
  152. it 'returns true' do
  153. expect(token.permissions?('foo.bar')).to be(true)
  154. end
  155. context 'but the permission is inactive' do
  156. before { permission.update(active: false) }
  157. it 'returns false' do
  158. expect(token.permissions?('foo.bar')).to be(false)
  159. end
  160. end
  161. end
  162. context 'when given a sibling sub-permission' do
  163. let(:sibling_permission) { create(:permission, name: 'foo.baz') }
  164. context 'that exists' do
  165. before { sibling_permission }
  166. it 'returns false' do
  167. expect(token.permissions?('foo.baz')).to be(false)
  168. end
  169. end
  170. context 'that does not exist' do
  171. it 'returns false' do
  172. expect(token.permissions?('foo.baz')).to be(false)
  173. end
  174. end
  175. end
  176. context 'when given the parent permission' do
  177. it 'returns false' do
  178. expect(token.permissions?('foo')).to be(false)
  179. end
  180. end
  181. context 'when given a glob' do
  182. context 'matching that sub-permission' do
  183. it 'returns true' do
  184. expect(token.permissions?('foo.*')).to be(true)
  185. end
  186. context 'but the permission is inactive' do
  187. before { permission.update(active: false) }
  188. context 'and user.permissions?(...) doesn’t fail' do
  189. let(:role) { create(:role, permissions: [parent_permission]) }
  190. let(:parent_permission) { create(:permission, name: permission_name.split('.').first) }
  191. it 'returns false' do
  192. expect(token.permissions?('foo.*')).to be(false)
  193. end
  194. end
  195. end
  196. end
  197. context 'NOT matching that sub-permission' do
  198. it 'returns false' do
  199. expect(token.permissions?('bar.*')).to be(false)
  200. end
  201. end
  202. end
  203. end
  204. end
  205. describe 'Attributes:' do
  206. describe '#persistent' do
  207. context 'when not set on creation' do
  208. subject(:token) { described_class.create(action: 'foo', user_id: User.first.id) }
  209. it 'defaults to nil' do
  210. expect(token.persistent).to be(nil)
  211. end
  212. end
  213. end
  214. end
  215. end