diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pleroma/registration.ex | 57 | ||||
-rw-r--r-- | lib/pleroma/user.ex | 18 | ||||
-rw-r--r-- | lib/pleroma/web/auth/authenticator.ex | 21 | ||||
-rw-r--r-- | lib/pleroma/web/auth/ldap_authenticator.ex | 15 | ||||
-rw-r--r-- | lib/pleroma/web/auth/pleroma_authenticator.ex | 66 | ||||
-rw-r--r-- | lib/pleroma/web/endpoint.ex | 18 | ||||
-rw-r--r-- | lib/pleroma/web/oauth/oauth_controller.ex | 219 | ||||
-rw-r--r-- | lib/pleroma/web/router.ex | 15 | ||||
-rw-r--r-- | lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex | 13 | ||||
-rw-r--r-- | lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex | 15 | ||||
-rw-r--r-- | lib/pleroma/web/templates/o_auth/o_auth/register.html.eex | 48 | ||||
-rw-r--r-- | lib/pleroma/web/templates/o_auth/o_auth/show.html.eex | 20 |
12 files changed, 479 insertions, 46 deletions
diff --git a/lib/pleroma/registration.ex b/lib/pleroma/registration.ex new file mode 100644 index 000000000..21fd1fc3f --- /dev/null +++ b/lib/pleroma/registration.ex @@ -0,0 +1,57 @@ +# 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 + + @primary_key {:id, Pleroma.FlakeId, autogenerate: true} + + schema "registrations" do + belongs_to(:user, User, type: Pleroma.FlakeId) + field(:provider, :string) + field(:uid, :string) + field(:info, :map, default: %{}) + + timestamps() + end + + def nickname(registration, default \\ nil), + do: Map.get(registration.info, "nickname", default) + + def email(registration, default \\ nil), + do: Map.get(registration.info, "email", default) + + def name(registration, default \\ nil), + do: Map.get(registration.info, "name", default) + + def description(registration, default \\ nil), + do: Map.get(registration.info, "description", default) + + def changeset(registration, params \\ %{}) do + registration + |> cast(params, [:user_id, :provider, :uid, :info]) + |> validate_required([:provider, :uid]) + |> foreign_key_constraint(:user_id) + |> unique_constraint(:uid, name: :registrations_provider_uid_index) + end + + def bind_to_user(registration, user) do + registration + |> changeset(%{user_id: (user && user.id) || nil}) + |> Repo.update() + end + + def get_by_provider_uid(provider, uid) do + Repo.get_by(Registration, + provider: to_string(provider), + uid: to_string(uid) + ) + end +end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index eb305dd95..cd1815b85 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -13,6 +13,7 @@ defmodule Pleroma.User do alias Pleroma.Formatter alias Pleroma.Notification alias Pleroma.Object + alias Pleroma.Registration alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web @@ -55,6 +56,7 @@ defmodule Pleroma.User do field(:bookmarks, {:array, :string}, default: []) field(:last_refreshed_at, :naive_datetime_usec) has_many(:notifications, Notification) + has_many(:registrations, Registration) embeds_one(:info, Pleroma.User.Info) timestamps() @@ -216,7 +218,7 @@ defmodule Pleroma.User do changeset = struct |> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation]) - |> validate_required([:email, :name, :nickname, :password, :password_confirmation]) + |> validate_required([:name, :nickname, :password, :password_confirmation]) |> validate_confirmation(:password) |> unique_constraint(:email) |> unique_constraint(:nickname) @@ -227,6 +229,13 @@ defmodule Pleroma.User do |> validate_length(:name, min: 1, max: 100) |> put_change(:info, info_change) + changeset = + if opts[:external] do + changeset + else + validate_required(changeset, [:email]) + end + if changeset.valid? do hashed = Pbkdf2.hashpwsalt(changeset.changes[:password]) ap_id = User.ap_id(%User{nickname: changeset.changes[:nickname]}) @@ -505,11 +514,10 @@ defmodule Pleroma.User do end end + def get_by_email(email), do: Repo.get_by(User, email: email) + def get_by_nickname_or_email(nickname_or_email) do - case user = Repo.get_by(User, nickname: nickname_or_email) do - %User{} -> user - nil -> Repo.get_by(User, email: nickname_or_email) - end + get_by_nickname(nickname_or_email) || get_by_email(nickname_or_email) end def get_cached_user_info(user) do diff --git a/lib/pleroma/web/auth/authenticator.ex b/lib/pleroma/web/auth/authenticator.ex index 82267c595..4eeef5034 100644 --- a/lib/pleroma/web/auth/authenticator.ex +++ b/lib/pleroma/web/auth/authenticator.ex @@ -3,6 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Web.Auth.Authenticator do + alias Pleroma.Registration alias Pleroma.User def implementation do @@ -12,8 +13,18 @@ defmodule Pleroma.Web.Auth.Authenticator do ) end - @callback get_user(Plug.Conn.t()) :: {:ok, User.t()} | {:error, any()} - def get_user(plug), do: implementation().get_user(plug) + @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 create_from_registration(Plug.Conn.t(), Map.t(), Registration.t()) :: + {:ok, User.t()} | {:error, any()} + def create_from_registration(plug, params, registration), + do: implementation().create_from_registration(plug, params, registration) + + @callback get_registration(Plug.Conn.t(), Map.t()) :: + {:ok, Registration.t()} | {:error, any()} + def get_registration(plug, params), + do: implementation().get_registration(plug, params) @callback handle_error(Plug.Conn.t(), any()) :: any() def handle_error(plug, error), do: implementation().handle_error(plug, error) @@ -22,4 +33,10 @@ defmodule Pleroma.Web.Auth.Authenticator do def auth_template do implementation().auth_template() || Pleroma.Config.get(:auth_template, "show.html") end + + @callback oauth_consumer_template() :: String.t() | nil + def oauth_consumer_template do + implementation().oauth_consumer_template() || + Pleroma.Config.get(:oauth_consumer_template, "consumer.html") + end end diff --git a/lib/pleroma/web/auth/ldap_authenticator.ex b/lib/pleroma/web/auth/ldap_authenticator.ex index 88217aab8..8b6d5a77f 100644 --- a/lib/pleroma/web/auth/ldap_authenticator.ex +++ b/lib/pleroma/web/auth/ldap_authenticator.ex @@ -8,14 +8,19 @@ defmodule Pleroma.Web.Auth.LDAPAuthenticator do require Logger @behaviour Pleroma.Web.Auth.Authenticator + @base Pleroma.Web.Auth.PleromaAuthenticator @connection_timeout 10_000 @search_timeout 10_000 - def get_user(%Plug.Conn{} = conn) do + defdelegate get_registration(conn, params), to: @base + + defdelegate create_from_registration(conn, params, registration), to: @base + + def get_user(%Plug.Conn{} = conn, params) do if Pleroma.Config.get([:ldap, :enabled]) do {name, password} = - case conn.params do + case params do %{"authorization" => %{"name" => name, "password" => password}} -> {name, password} @@ -29,14 +34,14 @@ defmodule Pleroma.Web.Auth.LDAPAuthenticator do {:error, {:ldap_connection_error, _}} -> # When LDAP is unavailable, try default authenticator - Pleroma.Web.Auth.PleromaAuthenticator.get_user(conn) + @base.get_user(conn, params) error -> error end else # Fall back to default authenticator - Pleroma.Web.Auth.PleromaAuthenticator.get_user(conn) + @base.get_user(conn, params) end end @@ -46,6 +51,8 @@ defmodule Pleroma.Web.Auth.LDAPAuthenticator do def auth_template, do: nil + def oauth_consumer_template, do: nil + defp ldap_user(name, password) do ldap = Pleroma.Config.get(:ldap, []) host = Keyword.get(ldap, :host, "localhost") diff --git a/lib/pleroma/web/auth/pleroma_authenticator.ex b/lib/pleroma/web/auth/pleroma_authenticator.ex index 94a19ad49..c826adb4c 100644 --- a/lib/pleroma/web/auth/pleroma_authenticator.ex +++ b/lib/pleroma/web/auth/pleroma_authenticator.ex @@ -4,13 +4,15 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticator do alias Comeonin.Pbkdf2 + alias Pleroma.Registration + alias Pleroma.Repo alias Pleroma.User @behaviour Pleroma.Web.Auth.Authenticator - def get_user(%Plug.Conn{} = conn) do + def get_user(%Plug.Conn{} = _conn, params) do {name, password} = - case conn.params do + case params do %{"authorization" => %{"name" => name, "password" => password}} -> {name, password} @@ -27,9 +29,69 @@ defmodule Pleroma.Web.Auth.PleromaAuthenticator do end end + def get_registration( + %Plug.Conn{assigns: %{ueberauth_auth: %{provider: provider, uid: uid} = auth}}, + _params + ) do + registration = Registration.get_by_provider_uid(provider, uid) + + if registration do + {:ok, registration} + else + info = auth.info + + Registration.changeset(%Registration{}, %{ + provider: to_string(provider), + uid: to_string(uid), + info: %{ + "nickname" => info.nickname, + "email" => info.email, + "name" => info.name, + "description" => info.description + } + }) + |> Repo.insert() + end + end + + def get_registration(%Plug.Conn{} = _conn, _params), do: {:error, :missing_credentials} + + def create_from_registration(_conn, params, registration) do + nickname = value([params["nickname"], Registration.nickname(registration)]) + email = value([params["email"], Registration.email(registration)]) + name = value([params["name"], Registration.name(registration)]) || nickname + bio = value([params["bio"], Registration.description(registration)]) + + random_password = :crypto.strong_rand_bytes(64) |> Base.encode64() + + with {:ok, new_user} <- + User.register_changeset( + %User{}, + %{ + email: email, + nickname: nickname, + name: name, + bio: bio, + password: random_password, + password_confirmation: random_password + }, + external: true, + confirmed: true + ) + |> Repo.insert(), + {:ok, _} <- + Registration.changeset(registration, %{user_id: new_user.id}) |> Repo.update() do + {:ok, new_user} + end + end + + defp value(list), do: Enum.find(list, &(to_string(&1) != "")) + def handle_error(%Plug.Conn{} = _conn, error) do error end def auth_template, do: nil + + def oauth_consumer_template, do: nil end diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index fa2d1cbe7..b85b95bf9 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -51,11 +51,22 @@ defmodule Pleroma.Web.Endpoint do plug(Plug.MethodOverride) plug(Plug.Head) + secure_cookies = Pleroma.Config.get([__MODULE__, :secure_cookie_flag]) + cookie_name = - if Application.get_env(:pleroma, Pleroma.Web.Endpoint) |> Keyword.get(:secure_cookie_flag), + if secure_cookies, do: "__Host-pleroma_key", else: "pleroma_key" + same_site = + if Pleroma.Config.get([:auth, :oauth_consumer_enabled]) do + # Note: "SameSite=Strict" prevents sign in with external OAuth provider + # (there would be no cookies during callback request from OAuth provider) + "SameSite=Lax" + else + "SameSite=Strict" + end + # The session will be stored in the cookie and signed, # this means its contents can be read but not tampered with. # Set :encryption_salt if you would also like to encrypt it. @@ -65,9 +76,8 @@ defmodule Pleroma.Web.Endpoint do key: cookie_name, signing_salt: {Pleroma.Config, :get, [[__MODULE__, :signing_salt], "CqaoopA2"]}, http_only: true, - secure: - Application.get_env(:pleroma, Pleroma.Web.Endpoint) |> Keyword.get(:secure_cookie_flag), - extra: "SameSite=Strict" + secure: secure_cookies, + extra: same_site ) plug(Pleroma.Web.Router) diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index 26d53df1a..1b467e983 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -5,6 +5,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do use Pleroma.Web, :controller + alias Pleroma.Registration alias Pleroma.Repo alias Pleroma.User alias Pleroma.Web.Auth.Authenticator @@ -15,6 +16,8 @@ defmodule Pleroma.Web.OAuth.OAuthController do import Pleroma.Web.ControllerHelper, only: [oauth_scopes: 2] + if Pleroma.Config.get([:auth, :oauth_consumer_enabled]), do: plug(Ueberauth) + plug(:fetch_session) plug(:fetch_flash) @@ -57,22 +60,16 @@ defmodule Pleroma.Web.OAuth.OAuthController do }) end - def create_authorization(conn, %{ - "authorization" => - %{ - "client_id" => client_id, - "redirect_uri" => redirect_uri - } = auth_params - }) do - with {_, {:ok, %User{} = user}} <- {:get_user, Authenticator.get_user(conn)}, - %App{} = app <- Repo.get_by(App, client_id: client_id), - true <- redirect_uri in String.split(app.redirect_uris), - scopes <- oauth_scopes(auth_params, []), - {:unsupported_scopes, []} <- {:unsupported_scopes, scopes -- app.scopes}, - # Note: `scope` param is intentionally not optional in this context - {:missing_scopes, false} <- {:missing_scopes, scopes == []}, - {:auth_active, true} <- {:auth_active, User.auth_active?(user)}, - {:ok, auth} <- Authorization.create_authorization(app, user, scopes) do + def create_authorization( + conn, + %{ + "authorization" => %{"redirect_uri" => redirect_uri} = auth_params + } = params, + opts \\ [] + ) do + with {:ok, auth} <- + (opts[:auth] && {:ok, opts[:auth]}) || + do_create_authorization(conn, params, opts[:user]) do redirect_uri = redirect_uri(conn, redirect_uri) cond do @@ -149,7 +146,7 @@ defmodule Pleroma.Web.OAuth.OAuthController do conn, %{"grant_type" => "password"} = params ) do - with {_, {:ok, %User{} = user}} <- {:get_user, Authenticator.get_user(conn)}, + with {_, {:ok, %User{} = user}} <- {:get_user, Authenticator.get_user(conn, params)}, %App{} = app <- get_app_from_request(conn, params), {:auth_active, true} <- {:auth_active, User.auth_active?(user)}, scopes <- oauth_scopes(params, app.scopes), @@ -205,6 +202,189 @@ defmodule Pleroma.Web.OAuth.OAuthController do end end + def prepare_request(conn, %{"provider" => provider} = params) do + scope = + oauth_scopes(params, []) + |> Enum.join(" ") + + state = + params + |> Map.delete("scopes") + |> Map.put("scope", scope) + |> Poison.encode!() + + params = + params + |> Map.drop(~w(scope scopes client_id redirect_uri)) + |> Map.put("state", state) + + redirect(conn, to: o_auth_path(conn, :request, provider, params)) + end + + def request(conn, params) do + message = + if params["provider"] do + "Unsupported OAuth provider: #{params["provider"]}." + else + "Bad OAuth request." + end + + conn + |> put_flash(:error, message) + |> redirect(to: "/") + end + + def callback(%{assigns: %{ueberauth_failure: failure}} = conn, params) do + params = callback_params(params) + messages = for e <- Map.get(failure, :errors, []), do: e.message + message = Enum.join(messages, "; ") + + conn + |> put_flash(:error, "Failed to authenticate: #{message}.") + |> redirect(external: redirect_uri(conn, params["redirect_uri"])) + end + + def callback(conn, params) do + params = callback_params(params) + + with {:ok, registration} <- Authenticator.get_registration(conn, params) do + user = Repo.preload(registration, :user).user + + auth_params = %{ + "client_id" => params["client_id"], + "redirect_uri" => params["redirect_uri"], + "scopes" => oauth_scopes(params, nil) + } + + if user do + create_authorization( + conn, + %{"authorization" => auth_params}, + user: user + ) + else + registration_params = + Map.merge(auth_params, %{ + "nickname" => Registration.nickname(registration), + "email" => Registration.email(registration) + }) + + conn + |> put_session(:registration_id, registration.id) + |> redirect(to: o_auth_path(conn, :registration_details, registration_params)) + end + else + _ -> + conn + |> put_flash(:error, "Failed to set up user account.") + |> redirect(external: redirect_uri(conn, params["redirect_uri"])) + end + end + + defp callback_params(%{"state" => state} = params) do + Map.merge(params, Poison.decode!(state)) + end + + def registration_details(conn, params) do + render(conn, "register.html", %{ + client_id: params["client_id"], + redirect_uri: params["redirect_uri"], + scopes: oauth_scopes(params, []), + nickname: params["nickname"], + email: params["email"] + }) + end + + def register(conn, %{"op" => "connect"} = params) do + create_authorization_params = %{ + "authorization" => Map.merge(params, %{"name" => params["auth_name"]}) + } + + with registration_id when not is_nil(registration_id) <- get_session_registration_id(conn), + %Registration{} = registration <- Repo.get(Registration, registration_id), + {:ok, auth} <- do_create_authorization(conn, create_authorization_params), + %User{} = user <- Repo.preload(auth, :user).user, + {:ok, _updated_registration} <- Registration.bind_to_user(registration, user) do + conn + |> put_session_registration_id(nil) + |> create_authorization( + create_authorization_params, + auth: auth + ) + else + _ -> + conn + |> put_flash(:error, "Unknown error, please try again.") + |> redirect(to: o_auth_path(conn, :registration_details, params)) + end + end + + def register(conn, params) do + with registration_id when not is_nil(registration_id) <- get_session_registration_id(conn), + %Registration{} = registration <- Repo.get(Registration, registration_id), + {:ok, user} <- Authenticator.create_from_registration(conn, params, registration) do + conn + |> put_session_registration_id(nil) + |> create_authorization( + %{ + "authorization" => %{ + "client_id" => params["client_id"], + "redirect_uri" => params["redirect_uri"], + "scopes" => oauth_scopes(params, nil) + } + }, + user: user + ) + else + {:error, changeset} -> + message = + Enum.map(changeset.errors, fn {field, {error, _}} -> + "#{field} #{error}" + end) + |> Enum.join("; ") + + message = + String.replace( + message, + "ap_id has already been taken", + "nickname has already been taken" + ) + + conn + |> put_flash(:error, "Error: #{message}.") + |> redirect(to: o_auth_path(conn, :registration_details, params)) + + _ -> + conn + |> put_flash(:error, "Unknown error, please try again.") + |> redirect(to: o_auth_path(conn, :registration_details, params)) + end + end + + defp do_create_authorization( + conn, + %{ + "authorization" => + %{ + "client_id" => client_id, + "redirect_uri" => redirect_uri + } = auth_params + } = params, + user \\ nil + ) do + with {_, {:ok, %User{} = user}} <- + {:get_user, (user && {:ok, user}) || Authenticator.get_user(conn, params)}, + %App{} = app <- Repo.get_by(App, client_id: client_id), + true <- redirect_uri in String.split(app.redirect_uris), + scopes <- oauth_scopes(auth_params, []), + {:unsupported_scopes, []} <- {:unsupported_scopes, scopes -- app.scopes}, + # Note: `scope` param is intentionally not optional in this context + {:missing_scopes, false} <- {:missing_scopes, scopes == []}, + {:auth_active, true} <- {:auth_active, User.auth_active?(user)} do + Authorization.create_authorization(app, user, scopes) + end + end + # XXX - for whatever reason our token arrives urlencoded, but Plug.Conn should be # decoding it. Investigate sometime. defp fix_padding(token) do @@ -242,4 +422,9 @@ defmodule Pleroma.Web.OAuth.OAuthController do defp redirect_uri(conn, "."), do: mastodon_api_url(conn, :login) defp redirect_uri(_conn, redirect_uri), do: redirect_uri + + defp get_session_registration_id(conn), do: get_session(conn, :registration_id) + + defp put_session_registration_id(conn, registration_id), + do: put_session(conn, :registration_id, registration_id) end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 605a327fc..5101e1b18 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -5,6 +5,11 @@ defmodule Pleroma.Web.Router do use Pleroma.Web, :router + pipeline :browser do + plug(:accepts, ["html"]) + plug(:fetch_session) + end + pipeline :oauth do plug(:fetch_session) plug(Pleroma.Plugs.OAuthPlug) @@ -209,6 +214,16 @@ defmodule Pleroma.Web.Router do post("/authorize", OAuthController, :create_authorization) post("/token", OAuthController, :token_exchange) post("/revoke", OAuthController, :token_revoke) + get("/registration_details", OAuthController, :registration_details) + + scope [] do + pipe_through(:browser) + + get("/prepare_request", OAuthController, :prepare_request) + get("/:provider", OAuthController, :request) + get("/:provider/callback", OAuthController, :callback) + post("/register", OAuthController, :register) + end end scope "/api/v1", Pleroma.Web.MastodonAPI do diff --git a/lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex new file mode 100644 index 000000000..4b8fb5dae --- /dev/null +++ b/lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex @@ -0,0 +1,13 @@ +<div class="scopes-input"> + <%= label @form, :scope, "Permissions" %> + + <div class="scopes"> + <%= for scope <- @available_scopes do %> + <%# Note: using hidden input with `unchecked_value` in order to distinguish user's empty selection from `scope` param being omitted %> + <div class="scope"> + <%= checkbox @form, :"scope_#{scope}", value: scope in @scopes && scope, checked_value: scope, unchecked_value: "", name: assigns[:scope_param] || "scope[]" %> + <%= label @form, :"scope_#{scope}", String.capitalize(scope) %> + </div> + <% end %> + </div> +</div> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex new file mode 100644 index 000000000..002f014e6 --- /dev/null +++ b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex @@ -0,0 +1,15 @@ +<br> +<br> +<h2>Sign in with external provider</h2> + +<%= form_for @conn, o_auth_path(@conn, :prepare_request), [method: "get"], fn f -> %> + <%= render @view_module, "_scopes.html", Map.put(assigns, :form, f) %> + + <%= hidden_input f, :client_id, value: @client_id %> + <%= hidden_input f, :redirect_uri, value: @redirect_uri %> + <%= hidden_input f, :state, value: @state %> + + <%= for strategy <- Pleroma.Config.get([:auth, :oauth_consumer_strategies], []) do %> + <%= submit "Sign in with #{String.capitalize(strategy)}", name: "provider", value: strategy %> + <% end %> +<% end %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/register.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/register.html.eex new file mode 100644 index 000000000..f4547170c --- /dev/null +++ b/lib/pleroma/web/templates/o_auth/o_auth/register.html.eex @@ -0,0 +1,48 @@ +<%= if get_flash(@conn, :info) do %> + <p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p> +<% end %> +<%= if get_flash(@conn, :error) do %> + <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p> +<% end %> + +<h2>Registration Details</h2> + +<p>If you'd like to register a new account, +<br> +please provide the details below.</p> +<br> + +<%= form_for @conn, o_auth_path(@conn, :register), [], fn f -> %> + +<div class="input"> + <%= label f, :nickname, "Nickname" %> + <%= text_input f, :nickname, value: @nickname %> +</div> +<div class="input"> + <%= label f, :email, "Email" %> + <%= text_input f, :email, value: @email %> +</div> + +<%= submit "Proceed as new user", name: "op", value: "register" %> + +<br> +<br> +<br> +<p>Alternatively, sign in to connect to existing account.</p> + +<div class="input"> + <%= label f, :auth_name, "Name or email" %> + <%= text_input f, :auth_name %> +</div> +<div class="input"> + <%= label f, :password, "Password" %> + <%= password_input f, :password %> +</div> + +<%= submit "Proceed as existing user", name: "op", value: "connect" %> + +<%= hidden_input f, :client_id, value: @client_id %> +<%= hidden_input f, :redirect_uri, value: @redirect_uri %> +<%= hidden_input f, :scope, value: Enum.join(@scopes, " ") %> + +<% end %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index 161333847..e6cf1db45 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -4,7 +4,9 @@ <%= if get_flash(@conn, :error) do %> <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p> <% end %> + <h2>OAuth Authorization</h2> + <%= form_for @conn, o_auth_path(@conn, :authorize), [as: "authorization"], fn f -> %> <div class="input"> <%= label f, :name, "Name or email" %> @@ -14,18 +16,8 @@ <%= label f, :password, "Password" %> <%= password_input f, :password %> </div> -<div class="scopes-input"> -<%= label f, :scope, "Permissions" %> - <div class="scopes"> - <%= for scope <- @available_scopes do %> - <%# Note: using hidden input with `unchecked_value` in order to distinguish user's empty selection from `scope` param being omitted %> - <div class="scope"> - <%= checkbox f, :"scope_#{scope}", value: scope in @scopes && scope, checked_value: scope, unchecked_value: "", name: "authorization[scope][]" %> - <%= label f, :"scope_#{scope}", String.capitalize(scope) %> - </div> - <% end %> - </div> -</div> + +<%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f, scope_param: "authorization[scope][]"}) %> <%= hidden_input f, :client_id, value: @client_id %> <%= hidden_input f, :response_type, value: @response_type %> @@ -33,3 +25,7 @@ <%= hidden_input f, :state, value: @state%> <%= submit "Authorize" %> <% end %> + +<%= if Pleroma.Config.get([:auth, :oauth_consumer_enabled]) do %> + <%= render @view_module, Pleroma.Web.Auth.Authenticator.oauth_consumer_template(), assigns %> +<% end %> |