Fork of Pleroma with site-specific changes and feature branches https://git.pleroma.social/pleroma/pleroma
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

106 řádky
3.4KB

  1. # Pleroma: A lightweight social networking server
  2. # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
  3. # SPDX-License-Identifier: AGPL-3.0-only
  4. defmodule Pleroma.Web.Auth.PleromaAuthenticator do
  5. alias Pleroma.Registration
  6. alias Pleroma.Repo
  7. alias Pleroma.User
  8. alias Pleroma.Web.Plugs.AuthenticationPlug
  9. import Pleroma.Web.Auth.Authenticator,
  10. only: [fetch_credentials: 1, fetch_user: 1]
  11. @behaviour Pleroma.Web.Auth.Authenticator
  12. def get_user(%Plug.Conn{} = conn) do
  13. with {:ok, {name, password}} <- fetch_credentials(conn),
  14. {_, %User{} = user} <- {:user, fetch_user(name)},
  15. {_, true} <- {:checkpw, AuthenticationPlug.checkpw(password, user.password_hash)},
  16. {:ok, user} <- AuthenticationPlug.maybe_update_password(user, password) do
  17. {:ok, user}
  18. else
  19. {:error, _reason} = error -> error
  20. error -> {:error, error}
  21. end
  22. end
  23. @doc """
  24. Gets or creates Pleroma.Registration record from Ueberauth assigns.
  25. Note: some strategies (like `keycloak`) might need extra configuration to fill `uid` from callback response —
  26. see [`docs/config.md`](docs/config.md).
  27. """
  28. def get_registration(%Plug.Conn{assigns: %{ueberauth_auth: %{uid: nil}}}),
  29. do: {:error, :missing_uid}
  30. def get_registration(%Plug.Conn{
  31. assigns: %{ueberauth_auth: %{provider: provider, uid: uid} = auth}
  32. }) do
  33. registration = Registration.get_by_provider_uid(provider, uid)
  34. if registration do
  35. {:ok, registration}
  36. else
  37. info = auth.info
  38. %Registration{}
  39. |> Registration.changeset(%{
  40. provider: to_string(provider),
  41. uid: to_string(uid),
  42. info: %{
  43. "nickname" => info.nickname,
  44. "email" => info.email,
  45. "name" => info.name,
  46. "description" => info.description
  47. }
  48. })
  49. |> Repo.insert()
  50. end
  51. end
  52. def get_registration(%Plug.Conn{} = _conn), do: {:error, :missing_credentials}
  53. @doc "Creates Pleroma.User record basing on params and Pleroma.Registration record."
  54. def create_from_registration(
  55. %Plug.Conn{params: %{"authorization" => registration_attrs}},
  56. %Registration{} = registration
  57. ) do
  58. nickname = value([registration_attrs["nickname"], Registration.nickname(registration)])
  59. email = value([registration_attrs["email"], Registration.email(registration)])
  60. name = value([registration_attrs["name"], Registration.name(registration)]) || nickname
  61. bio = value([registration_attrs["bio"], Registration.description(registration)]) || ""
  62. random_password = :crypto.strong_rand_bytes(64) |> Base.encode64()
  63. with {:ok, new_user} <-
  64. User.register_changeset(
  65. %User{},
  66. %{
  67. email: email,
  68. nickname: nickname,
  69. name: name,
  70. bio: bio,
  71. password: random_password,
  72. password_confirmation: random_password
  73. },
  74. external: true,
  75. need_confirmation: false
  76. )
  77. |> Repo.insert(),
  78. {:ok, _} <-
  79. Registration.changeset(registration, %{user_id: new_user.id}) |> Repo.update() do
  80. {:ok, new_user}
  81. end
  82. end
  83. defp value(list), do: Enum.find(list, &(to_string(&1) != ""))
  84. def handle_error(%Plug.Conn{} = _conn, error) do
  85. error
  86. end
  87. def auth_template, do: nil
  88. def oauth_consumer_template, do: nil
  89. end