logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma git clone https://hacktivis.me/git/pleroma.git

user_controller_test.exs (33621B)


  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.AdminAPI.UserControllerTest do
  5. use Pleroma.Web.ConnCase, async: false
  6. use Oban.Testing, repo: Pleroma.Repo
  7. import Mock
  8. import Pleroma.Factory
  9. alias Pleroma.HTML
  10. alias Pleroma.ModerationLog
  11. alias Pleroma.Repo
  12. alias Pleroma.Tests.ObanHelpers
  13. alias Pleroma.User
  14. alias Pleroma.Web.ActivityPub.Relay
  15. alias Pleroma.Web.CommonAPI
  16. alias Pleroma.Web.Endpoint
  17. alias Pleroma.Web.MediaProxy
  18. setup do
  19. Mox.stub_with(Pleroma.UnstubbedConfigMock, Pleroma.Config)
  20. :ok
  21. end
  22. setup_all do
  23. Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
  24. :ok
  25. end
  26. setup do
  27. admin = insert(:user, is_admin: true)
  28. token = insert(:oauth_admin_token, user: admin)
  29. conn =
  30. build_conn()
  31. |> assign(:user, admin)
  32. |> assign(:token, token)
  33. {:ok, %{admin: admin, token: token, conn: conn}}
  34. end
  35. test "with valid `admin_token` query parameter, skips OAuth scopes check" do
  36. clear_config([:instance, :admin_privileges], [:users_read])
  37. clear_config([:admin_token], "password123")
  38. user = insert(:user)
  39. conn = get(build_conn(), "/api/pleroma/admin/users/#{user.nickname}?admin_token=password123")
  40. assert json_response_and_validate_schema(conn, 200)
  41. end
  42. describe "DELETE /api/pleroma/admin/users" do
  43. test "single user", %{admin: admin, conn: conn} do
  44. clear_config([:instance, :federating], true)
  45. clear_config([:instance, :admin_privileges], [:users_delete])
  46. user =
  47. insert(:user,
  48. avatar: %{"url" => [%{"href" => "https://someurl"}]},
  49. banner: %{"url" => [%{"href" => "https://somebanner"}]},
  50. bio: "Hello world!",
  51. name: "A guy"
  52. )
  53. # Create some activities to check they got deleted later
  54. follower = insert(:user)
  55. {:ok, _} = CommonAPI.post(user, %{status: "test"})
  56. {:ok, _, _, _} = CommonAPI.follow(user, follower)
  57. {:ok, _, _, _} = CommonAPI.follow(follower, user)
  58. user = Repo.get(User, user.id)
  59. assert user.note_count == 1
  60. assert user.follower_count == 1
  61. assert user.following_count == 1
  62. assert user.is_active
  63. with_mock Pleroma.Web.Federator,
  64. publish: fn _ -> nil end,
  65. perform: fn _, _ -> nil end do
  66. conn =
  67. conn
  68. |> put_req_header("accept", "application/json")
  69. |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}")
  70. ObanHelpers.perform_all()
  71. refute User.get_by_nickname(user.nickname).is_active
  72. log_entry = Repo.one(ModerationLog)
  73. assert ModerationLog.get_log_entry_message(log_entry) ==
  74. "@#{admin.nickname} deleted users: @#{user.nickname}"
  75. assert json_response_and_validate_schema(conn, 200) == [user.nickname]
  76. user = Repo.get(User, user.id)
  77. refute user.is_active
  78. assert user.avatar == %{}
  79. assert user.banner == %{}
  80. assert user.note_count == 0
  81. assert user.follower_count == 0
  82. assert user.following_count == 0
  83. assert user.bio == ""
  84. assert user.name == nil
  85. assert called(Pleroma.Web.Federator.publish(:_))
  86. end
  87. end
  88. test "multiple users", %{admin: admin, conn: conn} do
  89. clear_config([:instance, :admin_privileges], [:users_delete])
  90. user_one = insert(:user)
  91. user_two = insert(:user)
  92. response =
  93. conn
  94. |> put_req_header("accept", "application/json")
  95. |> put_req_header("content-type", "application/json")
  96. |> delete("/api/pleroma/admin/users", %{
  97. nicknames: [user_one.nickname, user_two.nickname]
  98. })
  99. |> json_response_and_validate_schema(200)
  100. log_entry = Repo.one(ModerationLog)
  101. assert ModerationLog.get_log_entry_message(log_entry) ==
  102. "@#{admin.nickname} deleted users: @#{user_one.nickname}, @#{user_two.nickname}"
  103. assert response -- [user_one.nickname, user_two.nickname] == []
  104. end
  105. test "Needs privileged role", %{conn: conn} do
  106. clear_config([:instance, :admin_privileges], [])
  107. response =
  108. conn
  109. |> put_req_header("accept", "application/json")
  110. |> delete("/api/pleroma/admin/users?nickname=nickname")
  111. assert json_response(response, :forbidden)
  112. end
  113. end
  114. describe "/api/pleroma/admin/users" do
  115. test "Create", %{conn: conn} do
  116. response =
  117. conn
  118. |> put_req_header("accept", "application/json")
  119. |> put_req_header("content-type", "application/json")
  120. |> post("/api/pleroma/admin/users", %{
  121. "users" => [
  122. %{
  123. "nickname" => "lain",
  124. "email" => "lain@example.org",
  125. "password" => "test"
  126. },
  127. %{
  128. "nickname" => "lain2",
  129. "email" => "lain2@example.org",
  130. "password" => "test"
  131. }
  132. ]
  133. })
  134. |> json_response_and_validate_schema(200)
  135. |> Enum.map(&Map.get(&1, "type"))
  136. assert response == ["success", "success"]
  137. log_entry = Repo.one(ModerationLog)
  138. assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == []
  139. end
  140. test "Cannot create user with existing email", %{conn: conn} do
  141. user = insert(:user)
  142. conn =
  143. conn
  144. |> put_req_header("accept", "application/json")
  145. |> put_req_header("content-type", "application/json")
  146. |> post("/api/pleroma/admin/users", %{
  147. "users" => [
  148. %{
  149. "nickname" => "lain",
  150. "email" => user.email,
  151. "password" => "test"
  152. }
  153. ]
  154. })
  155. assert json_response_and_validate_schema(conn, 409) == [
  156. %{
  157. "code" => 409,
  158. "data" => %{
  159. "email" => user.email,
  160. "nickname" => "lain"
  161. },
  162. "error" => "email has already been taken",
  163. "type" => "error"
  164. }
  165. ]
  166. end
  167. test "Cannot create user with existing nickname", %{conn: conn} do
  168. user = insert(:user)
  169. conn =
  170. conn
  171. |> put_req_header("accept", "application/json")
  172. |> put_req_header("content-type", "application/json")
  173. |> post("/api/pleroma/admin/users", %{
  174. "users" => [
  175. %{
  176. "nickname" => user.nickname,
  177. "email" => "someuser@plerama.social",
  178. "password" => "test"
  179. }
  180. ]
  181. })
  182. assert json_response_and_validate_schema(conn, 409) == [
  183. %{
  184. "code" => 409,
  185. "data" => %{
  186. "email" => "someuser@plerama.social",
  187. "nickname" => user.nickname
  188. },
  189. "error" => "nickname has already been taken",
  190. "type" => "error"
  191. }
  192. ]
  193. end
  194. test "Multiple user creation works in transaction", %{conn: conn} do
  195. user = insert(:user)
  196. conn =
  197. conn
  198. |> put_req_header("accept", "application/json")
  199. |> put_req_header("content-type", "application/json")
  200. |> post("/api/pleroma/admin/users", %{
  201. "users" => [
  202. %{
  203. "nickname" => "newuser",
  204. "email" => "newuser@pleroma.social",
  205. "password" => "test"
  206. },
  207. %{
  208. "nickname" => "lain",
  209. "email" => user.email,
  210. "password" => "test"
  211. }
  212. ]
  213. })
  214. assert json_response_and_validate_schema(conn, 409) == [
  215. %{
  216. "code" => 409,
  217. "data" => %{
  218. "email" => user.email,
  219. "nickname" => "lain"
  220. },
  221. "error" => "email has already been taken",
  222. "type" => "error"
  223. },
  224. %{
  225. "code" => 409,
  226. "data" => %{
  227. "email" => "newuser@pleroma.social",
  228. "nickname" => "newuser"
  229. },
  230. "error" => "",
  231. "type" => "error"
  232. }
  233. ]
  234. assert User.get_by_nickname("newuser") === nil
  235. end
  236. end
  237. describe "GET /api/pleroma/admin/users/:nickname" do
  238. setup do
  239. clear_config([:instance, :admin_privileges], [:users_read])
  240. end
  241. test "returns 403 if not privileged with :users_read", %{conn: conn} do
  242. clear_config([:instance, :admin_privileges], [])
  243. conn = get(conn, "/api/pleroma/admin/users/user.nickname")
  244. assert json_response(conn, :forbidden)
  245. end
  246. test "Show", %{conn: conn} do
  247. user = insert(:user)
  248. conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}")
  249. assert user_response(user) == json_response_and_validate_schema(conn, 200)
  250. end
  251. test "when the user doesn't exist", %{conn: conn} do
  252. user = build(:user)
  253. conn = get(conn, "/api/pleroma/admin/users/#{user.nickname}")
  254. assert %{"error" => "Not found"} == json_response_and_validate_schema(conn, 404)
  255. end
  256. test "requires admin:read:accounts or broader scope",
  257. %{admin: admin} do
  258. user = insert(:user)
  259. url = "/api/pleroma/admin/users/#{user.nickname}"
  260. good_token1 = insert(:oauth_token, user: admin, scopes: ["admin"])
  261. good_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read"])
  262. good_token3 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts"])
  263. bad_token1 = insert(:oauth_token, user: admin, scopes: ["read:accounts"])
  264. bad_token2 = insert(:oauth_token, user: admin, scopes: ["admin:read:accounts:partial"])
  265. bad_token3 = nil
  266. for good_token <- [good_token1, good_token2, good_token3] do
  267. conn =
  268. build_conn()
  269. |> assign(:user, admin)
  270. |> assign(:token, good_token)
  271. |> get(url)
  272. assert json_response_and_validate_schema(conn, 200)
  273. end
  274. for good_token <- [good_token1, good_token2, good_token3] do
  275. conn =
  276. build_conn()
  277. |> assign(:user, nil)
  278. |> assign(:token, good_token)
  279. |> get(url)
  280. assert json_response(conn, :forbidden)
  281. end
  282. for bad_token <- [bad_token1, bad_token2, bad_token3] do
  283. conn =
  284. build_conn()
  285. |> assign(:user, admin)
  286. |> assign(:token, bad_token)
  287. |> get(url)
  288. assert json_response_and_validate_schema(conn, :forbidden)
  289. end
  290. end
  291. end
  292. describe "/api/pleroma/admin/users/follow" do
  293. test "allows to force-follow another user", %{admin: admin, conn: conn} do
  294. user = insert(:user)
  295. follower = insert(:user)
  296. conn
  297. |> put_req_header("accept", "application/json")
  298. |> put_req_header("content-type", "application/json")
  299. |> post("/api/pleroma/admin/users/follow", %{
  300. "follower" => follower.nickname,
  301. "followed" => user.nickname
  302. })
  303. user = User.get_cached_by_id(user.id)
  304. follower = User.get_cached_by_id(follower.id)
  305. assert User.following?(follower, user)
  306. log_entry = Repo.one(ModerationLog)
  307. assert ModerationLog.get_log_entry_message(log_entry) ==
  308. "@#{admin.nickname} made @#{follower.nickname} follow @#{user.nickname}"
  309. end
  310. end
  311. describe "/api/pleroma/admin/users/unfollow" do
  312. test "allows to force-unfollow another user", %{admin: admin, conn: conn} do
  313. user = insert(:user)
  314. follower = insert(:user)
  315. User.follow(follower, user)
  316. conn
  317. |> put_req_header("accept", "application/json")
  318. |> put_req_header("content-type", "application/json")
  319. |> post("/api/pleroma/admin/users/unfollow", %{
  320. "follower" => follower.nickname,
  321. "followed" => user.nickname
  322. })
  323. user = User.get_cached_by_id(user.id)
  324. follower = User.get_cached_by_id(follower.id)
  325. refute User.following?(follower, user)
  326. log_entry = Repo.one(ModerationLog)
  327. assert ModerationLog.get_log_entry_message(log_entry) ==
  328. "@#{admin.nickname} made @#{follower.nickname} unfollow @#{user.nickname}"
  329. end
  330. end
  331. describe "GET /api/pleroma/admin/users" do
  332. setup do
  333. clear_config([:instance, :admin_privileges], [:users_read])
  334. end
  335. test "returns 403 if not privileged with :users_read", %{conn: conn} do
  336. clear_config([:instance, :admin_privileges], [])
  337. conn = get(conn, "/api/pleroma/admin/users?page=1")
  338. assert json_response(conn, :forbidden)
  339. end
  340. test "renders users array for the first page", %{conn: conn, admin: admin} do
  341. user = insert(:user, local: false, tags: ["foo", "bar"])
  342. user2 = insert(:user, is_approved: false, registration_reason: "I'm a chill dude")
  343. conn = get(conn, "/api/pleroma/admin/users?page=1")
  344. users = [
  345. user_response(
  346. user2,
  347. %{
  348. "local" => true,
  349. "is_approved" => false,
  350. "registration_reason" => "I'm a chill dude",
  351. "actor_type" => "Person"
  352. }
  353. ),
  354. user_response(user, %{"local" => false, "tags" => ["foo", "bar"]}),
  355. user_response(
  356. admin,
  357. %{"roles" => %{"admin" => true, "moderator" => false}}
  358. )
  359. ]
  360. assert json_response_and_validate_schema(conn, 200) == %{
  361. "count" => 3,
  362. "page_size" => 50,
  363. "users" => users
  364. }
  365. end
  366. test "pagination works correctly with service users", %{conn: conn} do
  367. service1 = User.get_or_create_service_actor_by_ap_id(Endpoint.url() <> "/meido", "meido")
  368. insert_list(25, :user)
  369. assert %{"count" => 26, "page_size" => 10, "users" => users1} =
  370. conn
  371. |> get("/api/pleroma/admin/users?page=1&filters=", %{page_size: "10"})
  372. |> json_response_and_validate_schema(200)
  373. assert Enum.count(users1) == 10
  374. assert service1 not in users1
  375. assert %{"count" => 26, "page_size" => 10, "users" => users2} =
  376. conn
  377. |> get("/api/pleroma/admin/users?page=2&filters=", %{page_size: "10"})
  378. |> json_response_and_validate_schema(200)
  379. assert Enum.count(users2) == 10
  380. assert service1 not in users2
  381. assert %{"count" => 26, "page_size" => 10, "users" => users3} =
  382. conn
  383. |> get("/api/pleroma/admin/users?page=3&filters=", %{page_size: "10"})
  384. |> json_response_and_validate_schema(200)
  385. assert Enum.count(users3) == 6
  386. assert service1 not in users3
  387. end
  388. test "renders empty array for the second page", %{conn: conn} do
  389. insert(:user)
  390. conn = get(conn, "/api/pleroma/admin/users?page=2")
  391. assert json_response_and_validate_schema(conn, 200) == %{
  392. "count" => 2,
  393. "page_size" => 50,
  394. "users" => []
  395. }
  396. end
  397. test "regular search", %{conn: conn} do
  398. user = insert(:user, nickname: "bob")
  399. conn = get(conn, "/api/pleroma/admin/users?query=bo")
  400. assert json_response_and_validate_schema(conn, 200) == %{
  401. "count" => 1,
  402. "page_size" => 50,
  403. "users" => [user_response(user, %{"local" => true})]
  404. }
  405. end
  406. test "search by domain", %{conn: conn} do
  407. user = insert(:user, nickname: "nickname@domain.com")
  408. insert(:user)
  409. conn = get(conn, "/api/pleroma/admin/users?query=domain.com")
  410. assert json_response_and_validate_schema(conn, 200) == %{
  411. "count" => 1,
  412. "page_size" => 50,
  413. "users" => [user_response(user)]
  414. }
  415. end
  416. test "search by full nickname", %{conn: conn} do
  417. user = insert(:user, nickname: "nickname@domain.com")
  418. insert(:user)
  419. conn = get(conn, "/api/pleroma/admin/users?query=nickname@domain.com")
  420. assert json_response_and_validate_schema(conn, 200) == %{
  421. "count" => 1,
  422. "page_size" => 50,
  423. "users" => [user_response(user)]
  424. }
  425. end
  426. test "search by display name", %{conn: conn} do
  427. user = insert(:user, name: "Display name")
  428. insert(:user)
  429. conn = get(conn, "/api/pleroma/admin/users?name=display")
  430. assert json_response_and_validate_schema(conn, 200) == %{
  431. "count" => 1,
  432. "page_size" => 50,
  433. "users" => [user_response(user)]
  434. }
  435. end
  436. test "search by email", %{conn: conn} do
  437. user = insert(:user, email: "email@example.com")
  438. insert(:user)
  439. conn = get(conn, "/api/pleroma/admin/users?email=email@example.com")
  440. assert json_response_and_validate_schema(conn, 200) == %{
  441. "count" => 1,
  442. "page_size" => 50,
  443. "users" => [user_response(user)]
  444. }
  445. end
  446. test "regular search with page size", %{conn: conn} do
  447. user = insert(:user, nickname: "aalice")
  448. user2 = insert(:user, nickname: "alice")
  449. conn1 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=1")
  450. assert json_response_and_validate_schema(conn1, 200) == %{
  451. "count" => 2,
  452. "page_size" => 1,
  453. "users" => [user_response(user2)]
  454. }
  455. conn2 = get(conn, "/api/pleroma/admin/users?query=a&page_size=1&page=2")
  456. assert json_response_and_validate_schema(conn2, 200) == %{
  457. "count" => 2,
  458. "page_size" => 1,
  459. "users" => [user_response(user)]
  460. }
  461. end
  462. test "only local users" do
  463. admin = insert(:user, is_admin: true, nickname: "john")
  464. token = insert(:oauth_admin_token, user: admin)
  465. user = insert(:user, nickname: "bob")
  466. insert(:user, nickname: "bobb", local: false)
  467. conn =
  468. build_conn()
  469. |> assign(:user, admin)
  470. |> assign(:token, token)
  471. |> get("/api/pleroma/admin/users?query=bo&filters=local")
  472. assert json_response_and_validate_schema(conn, 200) == %{
  473. "count" => 1,
  474. "page_size" => 50,
  475. "users" => [user_response(user)]
  476. }
  477. end
  478. test "only local users with no query", %{conn: conn, admin: old_admin} do
  479. admin = insert(:user, is_admin: true, nickname: "john")
  480. user = insert(:user, nickname: "bob")
  481. insert(:user, nickname: "bobb", local: false)
  482. conn = get(conn, "/api/pleroma/admin/users?filters=local")
  483. users = [
  484. user_response(user),
  485. user_response(admin, %{
  486. "roles" => %{"admin" => true, "moderator" => false}
  487. }),
  488. user_response(old_admin, %{
  489. "is_active" => true,
  490. "roles" => %{"admin" => true, "moderator" => false}
  491. })
  492. ]
  493. assert json_response_and_validate_schema(conn, 200) == %{
  494. "count" => 3,
  495. "page_size" => 50,
  496. "users" => users
  497. }
  498. end
  499. test "only unconfirmed users", %{conn: conn} do
  500. sad_user = insert(:user, nickname: "sadboy", is_confirmed: false)
  501. old_user = insert(:user, nickname: "oldboy", is_confirmed: false)
  502. insert(:user, nickname: "happyboy", is_approved: true)
  503. insert(:user, is_confirmed: true)
  504. result =
  505. conn
  506. |> get("/api/pleroma/admin/users?filters=unconfirmed")
  507. |> json_response_and_validate_schema(200)
  508. users =
  509. Enum.map([old_user, sad_user], fn user ->
  510. user_response(user, %{
  511. "is_confirmed" => false,
  512. "is_approved" => true
  513. })
  514. end)
  515. assert result == %{"count" => 2, "page_size" => 50, "users" => users}
  516. end
  517. test "only unapproved users", %{conn: conn} do
  518. user =
  519. insert(:user,
  520. nickname: "sadboy",
  521. is_approved: false,
  522. registration_reason: "Plz let me in!"
  523. )
  524. insert(:user, nickname: "happyboy", is_approved: true)
  525. conn = get(conn, "/api/pleroma/admin/users?filters=need_approval")
  526. users = [
  527. user_response(
  528. user,
  529. %{"is_approved" => false, "registration_reason" => "Plz let me in!"}
  530. )
  531. ]
  532. assert json_response_and_validate_schema(conn, 200) == %{
  533. "count" => 1,
  534. "page_size" => 50,
  535. "users" => users
  536. }
  537. end
  538. test "load only admins", %{conn: conn, admin: admin} do
  539. second_admin = insert(:user, is_admin: true)
  540. insert(:user)
  541. insert(:user)
  542. conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
  543. users = [
  544. user_response(second_admin, %{
  545. "is_active" => true,
  546. "roles" => %{"admin" => true, "moderator" => false}
  547. }),
  548. user_response(admin, %{
  549. "is_active" => true,
  550. "roles" => %{"admin" => true, "moderator" => false}
  551. })
  552. ]
  553. assert json_response_and_validate_schema(conn, 200) == %{
  554. "count" => 2,
  555. "page_size" => 50,
  556. "users" => users
  557. }
  558. end
  559. test "load only moderators", %{conn: conn} do
  560. moderator = insert(:user, is_moderator: true)
  561. insert(:user)
  562. insert(:user)
  563. conn = get(conn, "/api/pleroma/admin/users?filters=is_moderator")
  564. assert json_response_and_validate_schema(conn, 200) == %{
  565. "count" => 1,
  566. "page_size" => 50,
  567. "users" => [
  568. user_response(moderator, %{
  569. "is_active" => true,
  570. "roles" => %{"admin" => false, "moderator" => true}
  571. })
  572. ]
  573. }
  574. end
  575. test "load users with actor_type is Person", %{admin: admin, conn: conn} do
  576. insert(:user, actor_type: "Service")
  577. insert(:user, actor_type: "Application")
  578. user1 = insert(:user)
  579. user2 = insert(:user)
  580. response =
  581. conn
  582. |> get(user_path(conn, :index), %{actor_types: ["Person"]})
  583. |> json_response_and_validate_schema(200)
  584. users = [
  585. user_response(user2),
  586. user_response(user1),
  587. user_response(admin, %{"roles" => %{"admin" => true, "moderator" => false}})
  588. ]
  589. assert response == %{"count" => 3, "page_size" => 50, "users" => users}
  590. end
  591. test "load users with actor_type is Person and Service", %{admin: admin, conn: conn} do
  592. user_service = insert(:user, actor_type: "Service")
  593. insert(:user, actor_type: "Application")
  594. user1 = insert(:user)
  595. user2 = insert(:user)
  596. response =
  597. conn
  598. |> get(user_path(conn, :index), %{actor_types: ["Person", "Service"]})
  599. |> json_response_and_validate_schema(200)
  600. users = [
  601. user_response(user2),
  602. user_response(user1),
  603. user_response(user_service, %{"actor_type" => "Service"}),
  604. user_response(admin, %{"roles" => %{"admin" => true, "moderator" => false}})
  605. ]
  606. assert response == %{"count" => 4, "page_size" => 50, "users" => users}
  607. end
  608. test "load users with actor_type is Service", %{conn: conn} do
  609. user_service = insert(:user, actor_type: "Service")
  610. insert(:user, actor_type: "Application")
  611. insert(:user)
  612. insert(:user)
  613. response =
  614. conn
  615. |> get(user_path(conn, :index), %{actor_types: ["Service"]})
  616. |> json_response_and_validate_schema(200)
  617. users = [user_response(user_service, %{"actor_type" => "Service"})]
  618. assert response == %{"count" => 1, "page_size" => 50, "users" => users}
  619. end
  620. test "load users with tags list", %{conn: conn} do
  621. user1 = insert(:user, tags: ["first"])
  622. user2 = insert(:user, tags: ["second"])
  623. insert(:user)
  624. insert(:user)
  625. conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
  626. users = [
  627. user_response(user2, %{"tags" => ["second"]}),
  628. user_response(user1, %{"tags" => ["first"]})
  629. ]
  630. assert json_response_and_validate_schema(conn, 200) == %{
  631. "count" => 2,
  632. "page_size" => 50,
  633. "users" => users
  634. }
  635. end
  636. test "`active` filters out users pending approval", %{token: token} do
  637. insert(:user, is_approved: false)
  638. %{id: user_id} = insert(:user, is_approved: true)
  639. %{id: admin_id} = token.user
  640. conn =
  641. build_conn()
  642. |> assign(:user, token.user)
  643. |> assign(:token, token)
  644. |> get("/api/pleroma/admin/users?filters=active")
  645. assert %{
  646. "count" => 2,
  647. "page_size" => 50,
  648. "users" => [
  649. %{"id" => ^user_id},
  650. %{"id" => ^admin_id}
  651. ]
  652. } = json_response_and_validate_schema(conn, 200)
  653. end
  654. test "it works with multiple filters" do
  655. admin = insert(:user, nickname: "john", is_admin: true)
  656. token = insert(:oauth_admin_token, user: admin)
  657. user = insert(:user, nickname: "bob", local: false, is_active: false)
  658. insert(:user, nickname: "ken", local: true, is_active: false)
  659. insert(:user, nickname: "bobb", local: false, is_active: true)
  660. conn =
  661. build_conn()
  662. |> assign(:user, admin)
  663. |> assign(:token, token)
  664. |> get("/api/pleroma/admin/users?filters=deactivated,external")
  665. assert json_response_and_validate_schema(conn, 200) == %{
  666. "count" => 1,
  667. "page_size" => 50,
  668. "users" => [user_response(user)]
  669. }
  670. end
  671. test "it omits relay user", %{admin: admin, conn: conn} do
  672. assert %User{} = Relay.get_actor()
  673. conn = get(conn, "/api/pleroma/admin/users")
  674. assert json_response_and_validate_schema(conn, 200) == %{
  675. "count" => 1,
  676. "page_size" => 50,
  677. "users" => [
  678. user_response(admin, %{"roles" => %{"admin" => true, "moderator" => false}})
  679. ]
  680. }
  681. end
  682. end
  683. test "PATCH /api/pleroma/admin/users/approve", %{admin: admin, conn: conn} do
  684. clear_config([:instance, :admin_privileges], [:users_manage_invites])
  685. user_one = insert(:user, is_approved: false)
  686. user_two = insert(:user, is_approved: false)
  687. conn =
  688. conn
  689. |> put_req_header("content-type", "application/json")
  690. |> patch(
  691. "/api/pleroma/admin/users/approve",
  692. %{nicknames: [user_one.nickname, user_two.nickname]}
  693. )
  694. response = json_response_and_validate_schema(conn, 200)
  695. assert Enum.map(response["users"], & &1["is_approved"]) == [true, true]
  696. log_entry = Repo.one(ModerationLog)
  697. assert ModerationLog.get_log_entry_message(log_entry) ==
  698. "@#{admin.nickname} approved users: @#{user_one.nickname}, @#{user_two.nickname}"
  699. end
  700. test "PATCH /api/pleroma/admin/users/approve returns 403 if not privileged with :users_manage_invites",
  701. %{conn: conn} do
  702. clear_config([:instance, :admin_privileges], [])
  703. conn =
  704. conn
  705. |> put_req_header("content-type", "application/json")
  706. |> patch(
  707. "/api/pleroma/admin/users/approve",
  708. %{nicknames: ["user_one.nickname", "user_two.nickname"]}
  709. )
  710. assert json_response(conn, :forbidden)
  711. end
  712. test "PATCH /api/pleroma/admin/users/suggest", %{admin: admin, conn: conn} do
  713. user1 = insert(:user, is_suggested: false)
  714. user2 = insert(:user, is_suggested: false)
  715. response =
  716. conn
  717. |> put_req_header("content-type", "application/json")
  718. |> patch(
  719. "/api/pleroma/admin/users/suggest",
  720. %{nicknames: [user1.nickname, user2.nickname]}
  721. )
  722. |> json_response_and_validate_schema(200)
  723. assert Enum.map(response["users"], & &1["is_suggested"]) == [true, true]
  724. [user1, user2] = Repo.reload!([user1, user2])
  725. assert user1.is_suggested
  726. assert user2.is_suggested
  727. log_entry = Repo.one(ModerationLog)
  728. assert ModerationLog.get_log_entry_message(log_entry) ==
  729. "@#{admin.nickname} added suggested users: @#{user1.nickname}, @#{user2.nickname}"
  730. end
  731. test "PATCH /api/pleroma/admin/users/unsuggest", %{admin: admin, conn: conn} do
  732. user1 = insert(:user, is_suggested: true)
  733. user2 = insert(:user, is_suggested: true)
  734. response =
  735. conn
  736. |> put_req_header("content-type", "application/json")
  737. |> patch(
  738. "/api/pleroma/admin/users/unsuggest",
  739. %{nicknames: [user1.nickname, user2.nickname]}
  740. )
  741. |> json_response_and_validate_schema(200)
  742. assert Enum.map(response["users"], & &1["is_suggested"]) == [false, false]
  743. [user1, user2] = Repo.reload!([user1, user2])
  744. refute user1.is_suggested
  745. refute user2.is_suggested
  746. log_entry = Repo.one(ModerationLog)
  747. assert ModerationLog.get_log_entry_message(log_entry) ==
  748. "@#{admin.nickname} removed suggested users: @#{user1.nickname}, @#{user2.nickname}"
  749. end
  750. describe "user activation" do
  751. test "PATCH /api/pleroma/admin/users/activate", %{admin: admin, conn: conn} do
  752. clear_config([:instance, :admin_privileges], [:users_manage_activation_state])
  753. user_one = insert(:user, is_active: false)
  754. user_two = insert(:user, is_active: false)
  755. conn =
  756. conn
  757. |> put_req_header("content-type", "application/json")
  758. |> patch(
  759. "/api/pleroma/admin/users/activate",
  760. %{nicknames: [user_one.nickname, user_two.nickname]}
  761. )
  762. response = json_response_and_validate_schema(conn, 200)
  763. assert Enum.map(response["users"], & &1["is_active"]) == [true, true]
  764. log_entry = Repo.one(ModerationLog)
  765. assert ModerationLog.get_log_entry_message(log_entry) ==
  766. "@#{admin.nickname} activated users: @#{user_one.nickname}, @#{user_two.nickname}"
  767. end
  768. test "PATCH /api/pleroma/admin/users/deactivate", %{admin: admin, conn: conn} do
  769. clear_config([:instance, :admin_privileges], [:users_manage_activation_state])
  770. user_one = insert(:user, is_active: true)
  771. user_two = insert(:user, is_active: true)
  772. conn =
  773. conn
  774. |> put_req_header("content-type", "application/json")
  775. |> patch(
  776. "/api/pleroma/admin/users/deactivate",
  777. %{nicknames: [user_one.nickname, user_two.nickname]}
  778. )
  779. response = json_response_and_validate_schema(conn, 200)
  780. assert Enum.map(response["users"], & &1["is_active"]) == [false, false]
  781. log_entry = Repo.one(ModerationLog)
  782. assert ModerationLog.get_log_entry_message(log_entry) ==
  783. "@#{admin.nickname} deactivated users: @#{user_one.nickname}, @#{user_two.nickname}"
  784. end
  785. test "PATCH /api/pleroma/admin/users/:nickname/toggle_activation", %{admin: admin, conn: conn} do
  786. clear_config([:instance, :admin_privileges], [:users_manage_activation_state])
  787. user = insert(:user)
  788. conn =
  789. conn
  790. |> put_req_header("content-type", "application/json")
  791. |> patch("/api/pleroma/admin/users/#{user.nickname}/toggle_activation")
  792. assert json_response_and_validate_schema(conn, 200) ==
  793. user_response(
  794. user,
  795. %{"is_active" => !user.is_active}
  796. )
  797. log_entry = Repo.one(ModerationLog)
  798. assert ModerationLog.get_log_entry_message(log_entry) ==
  799. "@#{admin.nickname} deactivated users: @#{user.nickname}"
  800. end
  801. test "it requires privileged role :statuses_activation to activate", %{conn: conn} do
  802. clear_config([:instance, :admin_privileges], [])
  803. conn =
  804. conn
  805. |> put_req_header("content-type", "application/json")
  806. |> patch(
  807. "/api/pleroma/admin/users/activate",
  808. %{nicknames: ["user_one.nickname", "user_two.nickname"]}
  809. )
  810. assert json_response(conn, :forbidden)
  811. end
  812. test "it requires privileged role :statuses_activation to deactivate", %{conn: conn} do
  813. clear_config([:instance, :admin_privileges], [])
  814. conn =
  815. conn
  816. |> put_req_header("content-type", "application/json")
  817. |> patch(
  818. "/api/pleroma/admin/users/deactivate",
  819. %{nicknames: ["user_one.nickname", "user_two.nickname"]}
  820. )
  821. assert json_response(conn, :forbidden)
  822. end
  823. test "it requires privileged role :statuses_activation to toggle activation", %{conn: conn} do
  824. clear_config([:instance, :admin_privileges], [])
  825. conn =
  826. conn
  827. |> put_req_header("content-type", "application/json")
  828. |> patch("/api/pleroma/admin/users/user.nickname/toggle_activation")
  829. assert json_response(conn, :forbidden)
  830. end
  831. end
  832. defp user_response(user, attrs \\ %{}) do
  833. %{
  834. "is_active" => user.is_active,
  835. "id" => user.id,
  836. "email" => user.email,
  837. "nickname" => user.nickname,
  838. "roles" => %{"admin" => false, "moderator" => false},
  839. "local" => user.local,
  840. "tags" => [],
  841. "avatar" => User.avatar_url(user) |> MediaProxy.url(),
  842. "display_name" => HTML.strip_tags(user.name || user.nickname),
  843. "is_confirmed" => true,
  844. "is_approved" => true,
  845. "is_suggested" => false,
  846. "url" => user.ap_id,
  847. "registration_reason" => nil,
  848. "actor_type" => "Person",
  849. "created_at" => CommonAPI.Utils.to_masto_date(user.inserted_at)
  850. }
  851. |> Map.merge(attrs)
  852. end
  853. end