permission_spec.rb 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677
  1. require 'rails_helper'
  2. RSpec.describe 'User endpoint', type: :request do
  3. let(:role_with_admin_user_permissions) do
  4. create(:role).tap do |role|
  5. role.permission_grant('admin.user')
  6. end
  7. end
  8. let(:admin_with_admin_user_permissions) { create(:user, roles: [role_with_admin_user_permissions]) }
  9. let(:role_without_admin_user_permissions) do
  10. create(:role).tap do |role|
  11. role.permission_grant('admin.tag')
  12. end
  13. end
  14. let(:admin_without_admin_user_permissions) { create(:user, roles: [role_without_admin_user_permissions]) }
  15. describe 'User creation' do
  16. let(:attributes) { attributes_params_for(:user) }
  17. it 'responds forbidden for customer' do
  18. requester = create(:customer)
  19. authenticated_as(requester)
  20. expect do
  21. post api_v1_users_path, params: attributes
  22. end.to not_change {
  23. User.count
  24. }
  25. expect(response).to have_http_status(:forbidden)
  26. end
  27. context 'privileged attributes' do
  28. context 'group assignment' do
  29. # group access assignment is in general only valid for agents
  30. # see HasGroups.groups_access_permission?
  31. let(:agent_attributes) do
  32. attributes.merge(
  33. roles: Role.where(name: 'Agent').map(&:name),
  34. )
  35. end
  36. shared_examples 'group assignment' do |map_method_id|
  37. it 'responds success for admin.user' do
  38. authenticated_as(admin_with_admin_user_permissions)
  39. expect do
  40. post api_v1_users_path, params: payload
  41. end.to change(User, :count).by(1)
  42. expect(response).to have_http_status(:success)
  43. expect(User.last.send(map_method_id)).to eq(send(map_method_id))
  44. end
  45. it 'responds forbidden for sub admin without admin.user' do
  46. authenticated_as(admin_without_admin_user_permissions)
  47. expect do
  48. post api_v1_users_path, params: payload
  49. end.to not_change {
  50. User.count
  51. }
  52. expect(response).to have_http_status(:forbidden)
  53. end
  54. it 'responds successful for agent but removes assignment' do
  55. requester = create(:agent)
  56. authenticated_as(requester)
  57. expect do
  58. post api_v1_users_path, params: payload
  59. end.to change(User, :count).by(1)
  60. expect(response).to have_http_status(:success)
  61. expect(User.last.send(map_method_id)).to be_blank
  62. end
  63. end
  64. context 'parameter groups' do
  65. let(:group_names_access_map) do
  66. Group.all.map { |g| [g.name, ['full']] }.to_h
  67. end
  68. let(:payload) do
  69. agent_attributes.merge(
  70. groups: group_names_access_map,
  71. )
  72. end
  73. it_behaves_like 'group assignment', :group_names_access_map
  74. end
  75. context 'parameter group_ids' do
  76. let(:group_ids_access_map) do
  77. Group.all.map { |g| [g.id, ['full']] }.to_h
  78. end
  79. let(:payload) do
  80. agent_attributes.merge(
  81. group_ids: group_ids_access_map,
  82. )
  83. end
  84. it_behaves_like 'group assignment', :group_ids_access_map
  85. end
  86. end
  87. context 'role assignment' do
  88. shared_examples 'role assignment' do
  89. let(:privileged) { Role.where(name: 'Admin') }
  90. it 'responds success for admin.user' do
  91. authenticated_as(admin_with_admin_user_permissions)
  92. expect do
  93. post api_v1_users_path, params: payload
  94. end.to change(User, :count).by(1)
  95. expect(response).to have_http_status(:success)
  96. expect(User.last.roles).to eq(privileged)
  97. end
  98. it 'responds forbidden for sub admin without admin.user' do
  99. authenticated_as(admin_without_admin_user_permissions)
  100. expect do
  101. post api_v1_users_path, params: payload
  102. end.to not_change {
  103. User.count
  104. }
  105. expect(response).to have_http_status(:forbidden)
  106. end
  107. it 'responds successful for agent but removes assignment' do
  108. requester = create(:agent)
  109. authenticated_as(requester)
  110. expect do
  111. post api_v1_users_path, params: payload
  112. end.to change(User, :count).by(1)
  113. expect(response).to have_http_status(:success)
  114. expect(User.last.roles).to eq(Role.signup_roles)
  115. end
  116. end
  117. context 'parameter roles' do
  118. let(:payload) do
  119. attributes.merge(
  120. roles: privileged.map(&:name),
  121. )
  122. end
  123. it_behaves_like 'role assignment'
  124. end
  125. context 'parameter role_ids' do
  126. let(:payload) do
  127. attributes.merge(
  128. role_ids: privileged.map(&:id),
  129. )
  130. end
  131. it_behaves_like 'role assignment'
  132. end
  133. end
  134. end
  135. end
  136. describe 'User update' do
  137. def authorized_update_request(requester:, requested:)
  138. authenticated_as(requester)
  139. expect do
  140. put api_v1_update_user_path(requested), params: cleaned_params_for(requested).merge(firstname: 'Changed')
  141. end.to change {
  142. requested.reload.firstname
  143. }
  144. expect(response).to have_http_status(:success)
  145. end
  146. def forbidden_update_request(requester:, requested:)
  147. authenticated_as(requester)
  148. expect do
  149. put api_v1_update_user_path(requested), params: cleaned_params_for(requested).merge(firstname: 'Changed')
  150. end.to not_change {
  151. requested.reload.attributes.tap do |attributes|
  152. # take attributes as they are for different users
  153. next if requester != requested
  154. # last_login and updated_at change every time
  155. # even if the record itself should not change
  156. attributes.delete_if do |key, _value|
  157. %w[last_login updated_at].include?(key)
  158. end
  159. end
  160. }
  161. expect(response).to have_http_status(:forbidden)
  162. end
  163. context 'request by admin.user' do
  164. let(:requester) { admin_with_admin_user_permissions }
  165. it 'is successful for same admin' do
  166. authorized_update_request(
  167. requester: requester,
  168. requested: requester,
  169. )
  170. end
  171. it 'is successful for other admin' do
  172. authorized_update_request(
  173. requester: requester,
  174. requested: create(:admin),
  175. )
  176. end
  177. it 'is successful for agent' do
  178. authorized_update_request(
  179. requester: requester,
  180. requested: create(:agent),
  181. )
  182. end
  183. it 'is successful for customer' do
  184. authorized_update_request(
  185. requester: requester,
  186. requested: create(:customer),
  187. )
  188. end
  189. end
  190. context 'request by sub admin without admin.user' do
  191. let(:requester) { admin_without_admin_user_permissions }
  192. it 'is forbidden for same admin' do
  193. forbidden_update_request(
  194. requester: requester,
  195. requested: requester,
  196. )
  197. end
  198. it 'is forbidden for other admin' do
  199. forbidden_update_request(
  200. requester: requester,
  201. requested: create(:admin),
  202. )
  203. end
  204. it 'is forbidden for agent' do
  205. forbidden_update_request(
  206. requester: requester,
  207. requested: create(:agent),
  208. )
  209. end
  210. it 'is forbidden for customer' do
  211. forbidden_update_request(
  212. requester: requester,
  213. requested: create(:customer),
  214. )
  215. end
  216. end
  217. context 'request by agent' do
  218. let(:requester) { create(:agent) }
  219. it 'is forbidden for admin' do
  220. forbidden_update_request(
  221. requester: requester,
  222. requested: create(:admin),
  223. )
  224. end
  225. it 'is forbidden same agent' do
  226. forbidden_update_request(
  227. requester: requester,
  228. requested: requester,
  229. )
  230. end
  231. it 'is forbidden for other agent' do
  232. forbidden_update_request(
  233. requester: requester,
  234. requested: create(:agent),
  235. )
  236. end
  237. it 'is successful for customer' do
  238. authorized_update_request(
  239. requester: requester,
  240. requested: create(:customer),
  241. )
  242. end
  243. end
  244. context 'request by customer' do
  245. let(:requester) { create(:customer) }
  246. it 'is forbidden for admin' do
  247. forbidden_update_request(
  248. requester: requester,
  249. requested: create(:admin),
  250. )
  251. end
  252. it 'is forbidden for agent' do
  253. forbidden_update_request(
  254. requester: requester,
  255. requested: create(:agent),
  256. )
  257. end
  258. it 'is forbidden for same customer' do
  259. forbidden_update_request(
  260. requester: requester,
  261. requested: requester,
  262. )
  263. end
  264. it 'is forbidden for other customer' do
  265. forbidden_update_request(
  266. requester: requester,
  267. requested: create(:customer),
  268. )
  269. end
  270. it 'is forbidden for same organization' do
  271. same_organization = create(:organization)
  272. requester.update!(organization: same_organization)
  273. forbidden_update_request(
  274. requester: requester,
  275. requested: create(:customer, organization: same_organization),
  276. )
  277. end
  278. end
  279. context 'privileged attributes' do
  280. let(:requested) { create(:user) }
  281. let(:attribute) { privileged.keys.first }
  282. let(:payload) { cleaned_params_for(requested).merge(privileged) }
  283. def value_of_attribute
  284. # we need to call .to_a otherwise Rails will load the
  285. # ActiveRecord::Associations::CollectionProxy
  286. # on comparsion which is to late
  287. requested.reload.public_send(attribute).to_a
  288. end
  289. shared_examples 'admin types requests' do
  290. it 'responds success for admin.user' do
  291. authenticated_as(admin_with_admin_user_permissions)
  292. expect do
  293. put api_v1_update_user_path(requested), params: payload
  294. end.to change {
  295. value_of_attribute
  296. }
  297. expect(response).to have_http_status(:success)
  298. end
  299. it 'responds forbidden for sub admin without admin.user' do
  300. authenticated_as(admin_without_admin_user_permissions)
  301. expect do
  302. put api_v1_update_user_path(requested), params: payload
  303. end.to not_change {
  304. value_of_attribute
  305. }
  306. expect(response).to have_http_status(:forbidden)
  307. end
  308. end
  309. shared_examples 'permitted agent update' do
  310. it 'responds successful for agent but removes assignment' do
  311. requester = create(:agent)
  312. authenticated_as(requester)
  313. expect do
  314. put api_v1_update_user_path(requested), params: payload
  315. end.to change {
  316. value_of_attribute
  317. }
  318. expect(response).to have_http_status(:success)
  319. end
  320. end
  321. shared_examples 'forbidden agent update' do
  322. it 'responds successful for agent but removes assignment' do
  323. requester = create(:agent)
  324. authenticated_as(requester)
  325. expect do
  326. put api_v1_update_user_path(requested), params: payload
  327. end.to not_change {
  328. value_of_attribute
  329. }
  330. expect(response).to have_http_status(:success)
  331. end
  332. end
  333. context 'group assignment' do
  334. context 'parameter groups' do
  335. let(:privileged) do
  336. {
  337. groups: Group.all.map { |g| [g.name, ['full']] }.to_h
  338. }
  339. end
  340. it_behaves_like 'admin types requests'
  341. it_behaves_like 'forbidden agent update'
  342. end
  343. context 'parameter group_ids' do
  344. let(:privileged) do
  345. {
  346. group_ids: Group.all.map { |g| [g.id, ['full']] }.to_h
  347. }
  348. end
  349. it_behaves_like 'admin types requests'
  350. it_behaves_like 'forbidden agent update'
  351. end
  352. end
  353. context 'role assignment' do
  354. let(:admin_role) { Role.where(name: 'Admin') }
  355. context 'parameter roles' do
  356. let(:privileged) do
  357. {
  358. roles: admin_role.map(&:name),
  359. }
  360. end
  361. it_behaves_like 'admin types requests'
  362. it_behaves_like 'forbidden agent update'
  363. end
  364. context 'parameter role_ids' do
  365. let(:privileged) do
  366. {
  367. role_ids: admin_role.map(&:id),
  368. }
  369. end
  370. it_behaves_like 'admin types requests'
  371. it_behaves_like 'forbidden agent update'
  372. end
  373. end
  374. context 'organization assignment' do
  375. let(:new_organizations) { create_list(:organization, 2) }
  376. context 'parameter organizations' do
  377. let(:privileged) do
  378. {
  379. organizations: new_organizations.map(&:name),
  380. }
  381. end
  382. it_behaves_like 'admin types requests'
  383. it_behaves_like 'permitted agent update'
  384. end
  385. context 'parameter organization_ids' do
  386. let(:privileged) do
  387. {
  388. organization_ids: new_organizations.map(&:id),
  389. }
  390. end
  391. it_behaves_like 'admin types requests'
  392. it_behaves_like 'permitted agent update'
  393. end
  394. end
  395. end
  396. end
  397. describe 'User deletion' do
  398. def authorized_destroy_request(requester:, requested:)
  399. authenticated_as(requester)
  400. delete api_v1_delete_user_path(requested)
  401. expect(response).to have_http_status(:success)
  402. expect(requested).not_to exist_in_database
  403. end
  404. def forbidden_destroy_request(requester:, requested:)
  405. authenticated_as(requester)
  406. delete api_v1_delete_user_path(requested)
  407. expect(response).to have_http_status(:forbidden)
  408. expect(requested).to exist_in_database
  409. end
  410. context 'request by admin.user' do
  411. let(:requester) { admin_with_admin_user_permissions }
  412. it 'is successful for same admin' do
  413. authorized_destroy_request(
  414. requester: requester,
  415. requested: requester,
  416. )
  417. end
  418. it 'is successful for other admin' do
  419. authorized_destroy_request(
  420. requester: requester,
  421. requested: create(:admin),
  422. )
  423. end
  424. it 'is successful for agent' do
  425. authorized_destroy_request(
  426. requester: requester,
  427. requested: create(:agent),
  428. )
  429. end
  430. it 'is successful for customer' do
  431. authorized_destroy_request(
  432. requester: requester,
  433. requested: create(:customer),
  434. )
  435. end
  436. end
  437. context 'request by sub admin without admin.user' do
  438. let(:requester) { admin_without_admin_user_permissions }
  439. it 'is forbidden for same admin' do
  440. forbidden_destroy_request(
  441. requester: requester,
  442. requested: requester,
  443. )
  444. end
  445. it 'is forbidden for other admin' do
  446. forbidden_destroy_request(
  447. requester: requester,
  448. requested: create(:admin),
  449. )
  450. end
  451. it 'is forbidden for agent' do
  452. forbidden_destroy_request(
  453. requester: requester,
  454. requested: create(:agent),
  455. )
  456. end
  457. it 'is forbidden for customer' do
  458. forbidden_destroy_request(
  459. requester: requester,
  460. requested: create(:customer),
  461. )
  462. end
  463. end
  464. context 'request by agent' do
  465. let(:requester) { create(:agent) }
  466. it 'is forbidden for admin' do
  467. forbidden_destroy_request(
  468. requester: requester,
  469. requested: create(:admin),
  470. )
  471. end
  472. it 'is forbidden same agent' do
  473. forbidden_destroy_request(
  474. requester: requester,
  475. requested: requester,
  476. )
  477. end
  478. it 'is forbidden for other agent' do
  479. forbidden_destroy_request(
  480. requester: requester,
  481. requested: create(:agent),
  482. )
  483. end
  484. it 'is forbidden for customer' do
  485. forbidden_destroy_request(
  486. requester: requester,
  487. requested: create(:customer),
  488. )
  489. end
  490. end
  491. context 'request by customer' do
  492. let(:requester) { create(:customer) }
  493. it 'is forbidden for admin' do
  494. forbidden_destroy_request(
  495. requester: requester,
  496. requested: create(:admin),
  497. )
  498. end
  499. it 'is forbidden for agent' do
  500. forbidden_destroy_request(
  501. requester: requester,
  502. requested: create(:agent),
  503. )
  504. end
  505. it 'is forbidden for same customer' do
  506. forbidden_destroy_request(
  507. requester: requester,
  508. requested: requester,
  509. )
  510. end
  511. it 'is forbidden for other customer' do
  512. forbidden_destroy_request(
  513. requester: requester,
  514. requested: create(:customer),
  515. )
  516. end
  517. it 'is forbidden for same organization' do
  518. same_organization = create(:organization)
  519. requester.update!(organization: same_organization)
  520. forbidden_destroy_request(
  521. requester: requester,
  522. requested: create(:customer, organization: same_organization),
  523. )
  524. end
  525. end
  526. end
  527. end