logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma

two_factor_authentication_controller_test.exs (9183B)


  1. defmodule Pleroma.Web.PleromaAPI.TwoFactorAuthenticationControllerTest do
  2. use Pleroma.Web.ConnCase
  3. import Pleroma.Factory
  4. alias Pleroma.MFA.Settings
  5. alias Pleroma.MFA.TOTP
  6. describe "GET /api/pleroma/accounts/mfa/settings" do
  7. test "returns user mfa settings for new user", %{conn: conn} do
  8. token = insert(:oauth_token, scopes: ["read", "follow"])
  9. token2 = insert(:oauth_token, scopes: ["write"])
  10. assert conn
  11. |> put_req_header("authorization", "Bearer #{token.token}")
  12. |> get("/api/pleroma/accounts/mfa")
  13. |> json_response(:ok) == %{
  14. "settings" => %{"enabled" => false, "totp" => false}
  15. }
  16. assert conn
  17. |> put_req_header("authorization", "Bearer #{token2.token}")
  18. |> get("/api/pleroma/accounts/mfa")
  19. |> json_response(403) == %{
  20. "error" => "Insufficient permissions: read:security."
  21. }
  22. end
  23. test "returns user mfa settings with enabled totp", %{conn: conn} do
  24. user =
  25. insert(:user,
  26. multi_factor_authentication_settings: %Settings{
  27. enabled: true,
  28. totp: %Settings.TOTP{secret: "XXX", delivery_type: "app", confirmed: true}
  29. }
  30. )
  31. token = insert(:oauth_token, scopes: ["read", "follow"], user: user)
  32. assert conn
  33. |> put_req_header("authorization", "Bearer #{token.token}")
  34. |> get("/api/pleroma/accounts/mfa")
  35. |> json_response(:ok) == %{
  36. "settings" => %{"enabled" => true, "totp" => true}
  37. }
  38. end
  39. end
  40. describe "GET /api/pleroma/accounts/mfa/backup_codes" do
  41. test "returns backup codes", %{conn: conn} do
  42. user =
  43. insert(:user,
  44. multi_factor_authentication_settings: %Settings{
  45. backup_codes: ["1", "2", "3"],
  46. totp: %Settings.TOTP{secret: "secret"}
  47. }
  48. )
  49. token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
  50. token2 = insert(:oauth_token, scopes: ["read"])
  51. response =
  52. conn
  53. |> put_req_header("authorization", "Bearer #{token.token}")
  54. |> get("/api/pleroma/accounts/mfa/backup_codes")
  55. |> json_response(:ok)
  56. assert [<<_::bytes-size(6)>>, <<_::bytes-size(6)>>] = response["codes"]
  57. user = refresh_record(user)
  58. mfa_settings = user.multi_factor_authentication_settings
  59. assert mfa_settings.totp.secret == "secret"
  60. refute mfa_settings.backup_codes == ["1", "2", "3"]
  61. refute mfa_settings.backup_codes == []
  62. assert conn
  63. |> put_req_header("authorization", "Bearer #{token2.token}")
  64. |> get("/api/pleroma/accounts/mfa/backup_codes")
  65. |> json_response(403) == %{
  66. "error" => "Insufficient permissions: write:security."
  67. }
  68. end
  69. end
  70. describe "GET /api/pleroma/accounts/mfa/setup/totp" do
  71. test "return errors when method is invalid", %{conn: conn} do
  72. user = insert(:user)
  73. token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
  74. response =
  75. conn
  76. |> put_req_header("authorization", "Bearer #{token.token}")
  77. |> get("/api/pleroma/accounts/mfa/setup/torf")
  78. |> json_response(400)
  79. assert response == %{"error" => "undefined method"}
  80. end
  81. test "returns key and provisioning_uri", %{conn: conn} do
  82. user =
  83. insert(:user,
  84. multi_factor_authentication_settings: %Settings{backup_codes: ["1", "2", "3"]}
  85. )
  86. token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
  87. token2 = insert(:oauth_token, scopes: ["read"])
  88. response =
  89. conn
  90. |> put_req_header("authorization", "Bearer #{token.token}")
  91. |> get("/api/pleroma/accounts/mfa/setup/totp")
  92. |> json_response(:ok)
  93. user = refresh_record(user)
  94. mfa_settings = user.multi_factor_authentication_settings
  95. secret = mfa_settings.totp.secret
  96. refute mfa_settings.enabled
  97. assert mfa_settings.backup_codes == ["1", "2", "3"]
  98. assert response == %{
  99. "key" => secret,
  100. "provisioning_uri" => TOTP.provisioning_uri(secret, "#{user.email}")
  101. }
  102. assert conn
  103. |> put_req_header("authorization", "Bearer #{token2.token}")
  104. |> get("/api/pleroma/accounts/mfa/setup/totp")
  105. |> json_response(403) == %{
  106. "error" => "Insufficient permissions: write:security."
  107. }
  108. end
  109. end
  110. describe "GET /api/pleroma/accounts/mfa/confirm/totp" do
  111. test "returns success result", %{conn: conn} do
  112. secret = TOTP.generate_secret()
  113. code = TOTP.generate_token(secret)
  114. user =
  115. insert(:user,
  116. multi_factor_authentication_settings: %Settings{
  117. backup_codes: ["1", "2", "3"],
  118. totp: %Settings.TOTP{secret: secret}
  119. }
  120. )
  121. token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
  122. token2 = insert(:oauth_token, scopes: ["read"])
  123. assert conn
  124. |> put_req_header("authorization", "Bearer #{token.token}")
  125. |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "test", code: code})
  126. |> json_response(:ok)
  127. settings = refresh_record(user).multi_factor_authentication_settings
  128. assert settings.enabled
  129. assert settings.totp.secret == secret
  130. assert settings.totp.confirmed
  131. assert settings.backup_codes == ["1", "2", "3"]
  132. assert conn
  133. |> put_req_header("authorization", "Bearer #{token2.token}")
  134. |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "test", code: code})
  135. |> json_response(403) == %{
  136. "error" => "Insufficient permissions: write:security."
  137. }
  138. end
  139. test "returns error if password incorrect", %{conn: conn} do
  140. secret = TOTP.generate_secret()
  141. code = TOTP.generate_token(secret)
  142. user =
  143. insert(:user,
  144. multi_factor_authentication_settings: %Settings{
  145. backup_codes: ["1", "2", "3"],
  146. totp: %Settings.TOTP{secret: secret}
  147. }
  148. )
  149. token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
  150. response =
  151. conn
  152. |> put_req_header("authorization", "Bearer #{token.token}")
  153. |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "xxx", code: code})
  154. |> json_response(422)
  155. settings = refresh_record(user).multi_factor_authentication_settings
  156. refute settings.enabled
  157. refute settings.totp.confirmed
  158. assert settings.backup_codes == ["1", "2", "3"]
  159. assert response == %{"error" => "Invalid password."}
  160. end
  161. test "returns error if code incorrect", %{conn: conn} do
  162. secret = TOTP.generate_secret()
  163. user =
  164. insert(:user,
  165. multi_factor_authentication_settings: %Settings{
  166. backup_codes: ["1", "2", "3"],
  167. totp: %Settings.TOTP{secret: secret}
  168. }
  169. )
  170. token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
  171. token2 = insert(:oauth_token, scopes: ["read"])
  172. response =
  173. conn
  174. |> put_req_header("authorization", "Bearer #{token.token}")
  175. |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "test", code: "code"})
  176. |> json_response(422)
  177. settings = refresh_record(user).multi_factor_authentication_settings
  178. refute settings.enabled
  179. refute settings.totp.confirmed
  180. assert settings.backup_codes == ["1", "2", "3"]
  181. assert response == %{"error" => "invalid_token"}
  182. assert conn
  183. |> put_req_header("authorization", "Bearer #{token2.token}")
  184. |> post("/api/pleroma/accounts/mfa/confirm/totp", %{password: "test", code: "code"})
  185. |> json_response(403) == %{
  186. "error" => "Insufficient permissions: write:security."
  187. }
  188. end
  189. end
  190. describe "DELETE /api/pleroma/accounts/mfa/totp" do
  191. test "returns success result", %{conn: conn} do
  192. user =
  193. insert(:user,
  194. multi_factor_authentication_settings: %Settings{
  195. backup_codes: ["1", "2", "3"],
  196. totp: %Settings.TOTP{secret: "secret"}
  197. }
  198. )
  199. token = insert(:oauth_token, scopes: ["write", "follow"], user: user)
  200. token2 = insert(:oauth_token, scopes: ["read"])
  201. assert conn
  202. |> put_req_header("authorization", "Bearer #{token.token}")
  203. |> delete("/api/pleroma/accounts/mfa/totp", %{password: "test"})
  204. |> json_response(:ok)
  205. settings = refresh_record(user).multi_factor_authentication_settings
  206. refute settings.enabled
  207. assert settings.totp.secret == nil
  208. refute settings.totp.confirmed
  209. assert conn
  210. |> put_req_header("authorization", "Bearer #{token2.token}")
  211. |> delete("/api/pleroma/accounts/mfa/totp", %{password: "test"})
  212. |> json_response(403) == %{
  213. "error" => "Insufficient permissions: write:security."
  214. }
  215. end
  216. end
  217. end