base: System.get_env("LDAP_BASE") || "dc=example,dc=com",
uid: System.get_env("LDAP_UID") || "cn"
-config :pleroma, :auth, oauth_consumer_enabled: false
+config :pleroma, :auth, oauth_consumer_enabled: System.get_env("OAUTH_CONSUMER_ENABLED") == "true"
config :ueberauth,
Ueberauth,
--- /dev/null
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Registration do
+ use Ecto.Schema
+
+ import Ecto.Changeset
+
+ alias Pleroma.Registration
+ alias Pleroma.Repo
+ alias Pleroma.User
+
+ schema "registrations" do
+ belongs_to(:user, User, type: Pleroma.FlakeId)
+ field(:provider, :string)
+ field(:uid, :string)
+ field(:info, :map, default: %{})
+
+ timestamps()
+ end
+
+ def changeset(registration, params \\ %{}) do
+ registration
+ |> cast(params, [:user_id, :provider, :uid, :info])
+ |> foreign_key_constraint(:user_id)
+ |> unique_constraint(:uid, name: :registrations_provider_uid_index)
+ end
+
+ def get_by_provider_uid(provider, uid) do
+ Repo.get_by(Registration,
+ provider: to_string(provider),
+ uid: to_string(uid)
+ )
+ end
+end
alias Pleroma.Formatter
alias Pleroma.Notification
alias Pleroma.Object
+ alias Pleroma.Registration
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Web
field(:email, :string)
field(:name, :string)
field(:nickname, :string)
- field(:auth_provider, :string)
- field(:auth_provider_uid, :string)
field(:password_hash, :string)
field(:password, :string, virtual: true)
field(:password_confirmation, :string, virtual: true)
field(:bookmarks, {:array, :string}, default: [])
field(:last_refreshed_at, :naive_datetime)
has_many(:notifications, Notification)
+ has_many(:registrations, Registration)
embeds_one(:info, Pleroma.User.Info)
timestamps()
end
# TODO: FIXME (WIP):
- def oauth_register_changeset(struct, params \\ %{}) do
+ def external_registration_changeset(struct, params \\ %{}) do
info_change = User.Info.confirmation_changeset(%User.Info{}, :confirmed)
changeset =
struct
- |> cast(params, [:email, :nickname, :name, :bio, :auth_provider, :auth_provider_uid])
- |> validate_required([:auth_provider, :auth_provider_uid])
+ |> cast(params, [:email, :nickname, :name, :bio])
|> unique_constraint(:email)
|> unique_constraint(:nickname)
|> validate_exclusion(:nickname, Pleroma.Config.get([Pleroma.User, :restricted_nicknames]))
get_by_nickname(nickname_or_email) || get_by_email(nickname_or_email)
end
- def get_by_auth_provider_uid(auth_provider, auth_provider_uid),
- do:
- Repo.get_by(User,
- auth_provider: to_string(auth_provider),
- auth_provider_uid: to_string(auth_provider_uid)
- )
-
def get_cached_user_info(user) do
key = "user_info:#{user.id}"
Cachex.fetch!(:user_cache, key, fn _ -> user_info(user) end)
@callback get_user(Plug.Conn.t(), Map.t()) :: {:ok, User.t()} | {:error, any()}
def get_user(plug, params), do: implementation().get_user(plug, params)
- @callback get_or_create_user_by_oauth(Plug.Conn.t(), Map.t()) ::
+ @callback get_by_external_registration(Plug.Conn.t(), Map.t()) ::
{:ok, User.t()} | {:error, any()}
- def get_or_create_user_by_oauth(plug, params),
- do: implementation().get_or_create_user_by_oauth(plug, params)
+ def get_by_external_registration(plug, params),
+ do: implementation().get_by_external_registration(plug, params)
@callback handle_error(Plug.Conn.t(), any()) :: any()
def handle_error(plug, error), do: implementation().handle_error(plug, error)
end
end
- def get_or_create_user_by_oauth(conn, params), do: get_user(conn, params)
+ def get_by_external_registration(conn, params), do: get_user(conn, params)
def handle_error(%Plug.Conn{} = _conn, error) do
error
defmodule Pleroma.Web.Auth.PleromaAuthenticator do
alias Comeonin.Pbkdf2
alias Pleroma.User
+ alias Pleroma.Registration
+ alias Pleroma.Repo
@behaviour Pleroma.Web.Auth.Authenticator
end
end
- def get_or_create_user_by_oauth(
+ def get_by_external_registration(
%Plug.Conn{assigns: %{ueberauth_auth: %{provider: provider, uid: uid} = auth}},
_params
) do
- user = User.get_by_auth_provider_uid(provider, uid)
+ registration = Registration.get_by_provider_uid(provider, uid)
- if user do
+ if registration do
+ user = Repo.preload(registration, :user).user
{:ok, user}
else
info = auth.info
email = info.email
nickname = info.nickname
- # TODO: FIXME: connect to existing (non-oauth) account (need a UI flow for that) / generate a random nickname?
+ # Note: nullifying email in case this email is already taken
email =
if email && User.get_by_email(email) do
nil
email
end
+ # Note: generating a random numeric suffix to nickname in case this nickname is already taken
nickname =
if nickname && User.get_by_nickname(nickname) do
- nil
+ "#{nickname}_#{:os.system_time()}"
else
nickname
end
- new_user =
- User.oauth_register_changeset(
- %User{},
- %{
- auth_provider: to_string(provider),
- auth_provider_uid: to_string(uid),
- name: info.name,
- bio: info.description,
- email: email,
- nickname: nickname
- }
- )
-
- Pleroma.Repo.insert(new_user)
+ with {:ok, new_user} <-
+ User.external_registration_changeset(
+ %User{},
+ %{
+ name: info.name,
+ bio: info.description,
+ email: email,
+ nickname: nickname
+ }
+ )
+ |> Repo.insert(),
+ {:ok, _} <-
+ Registration.changeset(%Registration{}, %{
+ user_id: new_user.id,
+ provider: to_string(provider),
+ uid: to_string(uid),
+ info: %{nickname: info.nickname, email: info.email}
+ })
+ |> Repo.insert() do
+ {:ok, new_user}
+ end
end
end
- def get_or_create_user_by_oauth(%Plug.Conn{} = _conn, _params),
+ def get_by_external_registration(%Plug.Conn{} = _conn, _params),
do: {:error, :missing_credentials}
def handle_error(%Plug.Conn{} = _conn, error) do
conn,
%{"client_id" => client_id, "redirect_uri" => redirect_uri} = params
) do
- with {:ok, user} <- Authenticator.get_or_create_user_by_oauth(conn, params) do
+ with {:ok, user} <- Authenticator.get_by_external_registration(conn, params) do
do_create_authorization(
conn,
%{
+++ /dev/null
-defmodule Pleroma.Repo.Migrations.AddAuthProviderAndAuthProviderUidToUsers do
- use Ecto.Migration
-
- def change do
- alter table(:users) do
- add :auth_provider, :string
- add :auth_provider_uid, :string
- end
-
- create unique_index(:users, [:auth_provider, :auth_provider_uid])
- end
-end
--- /dev/null
+defmodule Pleroma.Repo.Migrations.CreateRegistrations do
+ use Ecto.Migration
+
+ def change do
+ create table(:registrations) do
+ add :user_id, references(:users, type: :uuid, on_delete: :delete_all)
+ add :provider, :string
+ add :uid, :string
+ add :info, :map, default: %{}
+
+ timestamps()
+ end
+
+ create unique_index(:registrations, [:provider, :uid])
+ end
+end