mirror of
https://github.com/netfun2000/hipudding-teslamate.git
synced 2026-02-27 09:44:28 +08:00
Remove support for legacy auth
This commit is contained in:
@@ -10,19 +10,6 @@ defmodule TeslaApi.Auth do
|
||||
defdelegate login(email, password), to: MFA
|
||||
defdelegate login(device_id, mfa_passcode, ctx), to: MFA
|
||||
|
||||
def legacy_login(email, password) do
|
||||
data = %{
|
||||
grant_type: "password",
|
||||
client_id: @client_id,
|
||||
client_secret: @client_secret,
|
||||
email: email,
|
||||
password: password
|
||||
}
|
||||
|
||||
TeslaApi.post("/oauth/token", data)
|
||||
|> handle_response()
|
||||
end
|
||||
|
||||
def refresh(%__MODULE__{token: token, refresh_token: refresh_token}) do
|
||||
data = %{
|
||||
grant_type: "refresh_token",
|
||||
@@ -35,11 +22,6 @@ defmodule TeslaApi.Auth do
|
||||
|> handle_response()
|
||||
end
|
||||
|
||||
def revoke(%__MODULE__{token: token}) do
|
||||
TeslaApi.post("/oauth/revoke", %{token: token}, opts: [access_token: token])
|
||||
|> handle_response()
|
||||
end
|
||||
|
||||
defp handle_response(response) do
|
||||
case response do
|
||||
{:ok, %Tesla.Env{status: 200, body: body}} when body == %{} ->
|
||||
|
||||
@@ -115,7 +115,6 @@ defmodule TeslaMate.Api do
|
||||
@impl true
|
||||
def handle_call({:sign_in, args}, _, state) do
|
||||
case args do
|
||||
[%Credentials{use_legacy_auth: true} = c] -> Auth.legacy_login(c.email, c.password)
|
||||
[%Credentials{} = c] -> Auth.login(c.email, c.password)
|
||||
[device_id, passcode, ctx] -> Auth.login(device_id, passcode, ctx)
|
||||
end
|
||||
|
||||
@@ -5,13 +5,12 @@ defmodule TeslaMate.Auth.Credentials do
|
||||
schema "" do
|
||||
field :email, :string
|
||||
field :password, :string
|
||||
field :use_legacy_auth, :boolean, default: false
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(credentials, attrs) do
|
||||
credentials
|
||||
|> cast(attrs, [:email, :password, :use_legacy_auth])
|
||||
|> cast(attrs, [:email, :password])
|
||||
|> validate_required([:email, :password])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -13,26 +13,24 @@ defmodule TeslaMateWeb.SignInLive.Index do
|
||||
page_title: gettext("Sign in"),
|
||||
error: nil,
|
||||
task: nil,
|
||||
state: {:credentials, {Auth.change_credentials(), _show_checkbox = false}}
|
||||
state: {:credentials, Auth.change_credentials()}
|
||||
}
|
||||
|
||||
{:ok, assign(socket, assigns)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("validate", %{"credentials" => c}, %{assigns: %{state: {:credentials, d}}} = s) do
|
||||
{_changeset, show_checkbox?} = d
|
||||
|
||||
def handle_event("validate", %{"credentials" => c}, %{assigns: %{state: {:credentials, _}}} = s) do
|
||||
changeset =
|
||||
c
|
||||
|> Auth.change_credentials()
|
||||
|> Map.put(:action, :update)
|
||||
|
||||
{:noreply, assign(s, state: {:credentials, {changeset, show_checkbox?}}, error: nil)}
|
||||
{:noreply, assign(s, state: {:credentials, changeset}, error: nil)}
|
||||
end
|
||||
|
||||
def handle_event("validate", %{"mfa" => mfa}, %{assigns: %{state: {:mfa, data}}} = socket) do
|
||||
{_changeset, devices, ctx, show_button?} = data
|
||||
{_changeset, devices, ctx} = data
|
||||
|
||||
changeset =
|
||||
mfa
|
||||
@@ -48,12 +46,12 @@ defmodule TeslaMateWeb.SignInLive.Index do
|
||||
end)
|
||||
end
|
||||
|
||||
state = {:mfa, {changeset, devices, ctx, show_button?}}
|
||||
state = {:mfa, {changeset, devices, ctx}}
|
||||
|
||||
{:noreply, assign(socket, state: state, task: task, error: nil)}
|
||||
end
|
||||
|
||||
def handle_event("sign_in", _, %{assigns: %{state: {:credentials, {changeset, _}}}} = socket) do
|
||||
def handle_event("sign_in", _, %{assigns: %{state: {:credentials, changeset}}} = socket) do
|
||||
credentials = Ecto.Changeset.apply_changes(changeset)
|
||||
|
||||
task =
|
||||
@@ -64,11 +62,6 @@ defmodule TeslaMateWeb.SignInLive.Index do
|
||||
{:noreply, assign(socket, task: task)}
|
||||
end
|
||||
|
||||
def handle_event("use_legacy_login", _params, %{assigns: %{state: {:mfa, _data}}} = socket) do
|
||||
state = {:credentials, {Auth.change_credentials(%{use_legacy_auth: true}), true}}
|
||||
{:noreply, assign(socket, state: state)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info({ref, result}, %{assigns: %{task: %Task{ref: ref}}} = socket) do
|
||||
Process.demonitor(ref, [:flush])
|
||||
@@ -80,20 +73,11 @@ defmodule TeslaMateWeb.SignInLive.Index do
|
||||
|
||||
{:ok, {:mfa, devices, ctx}} ->
|
||||
devices = Enum.map(devices, fn %{"name" => name, "id" => id} -> {name, id} end)
|
||||
state = {:mfa, {mfa_changeset(), devices, ctx, false}}
|
||||
state = {:mfa, {mfa_changeset(), devices, ctx}}
|
||||
{:noreply, assign(socket, state: state, task: nil)}
|
||||
|
||||
{:error, %TeslaApi.Error{} = e} ->
|
||||
state =
|
||||
case socket.assigns.state do
|
||||
{:credentials, {changeset, _show_checkbox}} ->
|
||||
{:credentials, {changeset, true}}
|
||||
|
||||
{:mfa, {changeset, devices, ctx, _show_button}} ->
|
||||
{:mfa, {changeset, devices, ctx, true}}
|
||||
end
|
||||
|
||||
{:noreply, assign(socket, state: state, error: Exception.message(e), task: nil)}
|
||||
{:noreply, assign(socket, error: Exception.message(e), task: nil)}
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="mfa columns is-tablet is-centered">
|
||||
<div class="column is-half">
|
||||
<%= case @state do %>
|
||||
<% {:credentials, {changeset, show_checkbox?}} -> %>
|
||||
<% {:credentials, changeset} -> %>
|
||||
<%= f = form_for changeset, "#", [phx_change: :validate, phx_submit: :sign_in, class: "box"] %>
|
||||
<%= if @error do %>
|
||||
<div class="notification is-danger">
|
||||
@@ -34,17 +34,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= if show_checkbox? do %>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<label class="checkbox">
|
||||
<%= checkbox f, :use_legacy_auth, disabled: !!@task %>
|
||||
<%= gettext "Use legacy authentication API" %>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="field mt-20">
|
||||
<div class="control">
|
||||
<%= submit gettext("Sign in"), class: "button is-rounded is-fullwidth is-link#{if !!@task, do: " is-loading" }",
|
||||
@@ -55,7 +44,7 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<% {:mfa, {changeset, devices, _ctx, show_button?}} -> %>
|
||||
<% {:mfa, {changeset, devices, _ctx}} -> %>
|
||||
<%= f = form_for changeset, "#", [phx_change: :validate, class: "box", as: :mfa] %>
|
||||
<h3 class="title is-4 is-spaced has-text-centered">
|
||||
<%= gettext "Two-Factor Authentication" %>
|
||||
@@ -92,21 +81,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<%= if show_button? do %>
|
||||
<hr style="margin-top: 0;"/>
|
||||
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<button type="button" class="button is-warning is-light is-small is-rounded is-fullwidth"
|
||||
phx-click="use_legacy_login" <%= if !!@task, do: "disabled" %>>
|
||||
<span class="icon"><i class="mdi mdi-login"></i></span> <span><%=
|
||||
gettext "Use legacy authentication API"
|
||||
%></span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</form>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
@@ -55,10 +55,6 @@ defmodule TeslaMate.ApiTest do
|
||||
send(pid, {TeslaApi.Auth, {:login, email, password}})
|
||||
{:ok, %TeslaApi.Auth{token: "$token", refresh_token: "$token", expires_in: 10_000_000}}
|
||||
end,
|
||||
legacy_login: fn email, password ->
|
||||
send(pid, {TeslaApi.Auth, {:legacy_login, email, password}})
|
||||
{:ok, %TeslaApi.Auth{token: "$token", refresh_token: "$token", expires_in: 10_000_000}}
|
||||
end,
|
||||
refresh: fn
|
||||
%{token: "cannot_be_refreshed", refresh_token: "cannot_be_refreshed"} = auth ->
|
||||
send(pid, {TeslaApi.Auth, {:refresh, auth}})
|
||||
@@ -144,23 +140,6 @@ defmodule TeslaMate.ApiTest do
|
||||
end
|
||||
end
|
||||
|
||||
test "uses legacy login", %{test: name} do
|
||||
with_mocks [auth_mock(self()), vehicle_mock(self())] do
|
||||
:ok = start_api(name, tokens: nil)
|
||||
|
||||
assert false == Api.signed_in?(name)
|
||||
|
||||
assert :ok = Api.sign_in(name, %Credentials{@valid_credentials | use_legacy_auth: true})
|
||||
|
||||
assert_receive {TeslaApi.Auth, {:legacy_login, "teslamate", "foo"}}
|
||||
assert_receive {AuthMock, {:save, %TeslaApi.Auth{}}}
|
||||
assert_receive {VehiclesMock, :restart}
|
||||
assert true == Api.signed_in?(name)
|
||||
|
||||
refute_receive _
|
||||
end
|
||||
end
|
||||
|
||||
test "fails if already signed in", %{test: name} do
|
||||
with_mocks [auth_mock(self()), vehicle_mock(self())] do
|
||||
:ok = start_api(name, tokens: @valid_tokens)
|
||||
|
||||
@@ -89,73 +89,4 @@ defmodule TeslaMateWeb.SignInLiveTest do
|
||||
assert_receive {ApiMock, {:sign_in, "111", "123456", %TeslaApi.Auth.MFA.Ctx{}}}
|
||||
assert_redirect(view, "/", 1000)
|
||||
end
|
||||
|
||||
test "offers to sign in via the legacy API", %{conn: conn, test: name} do
|
||||
params = start_api(name)
|
||||
|
||||
assert {:ok, view, html} =
|
||||
conn
|
||||
|> put_connect_params(params)
|
||||
|> live("/sign_in")
|
||||
|
||||
assert [] ==
|
||||
html
|
||||
|> Floki.parse_document!()
|
||||
|> Floki.find("#credentials_use_legacy_auth")
|
||||
|
||||
render_change(view, :validate, %{credentials: %{email: "error", password: "…"}})
|
||||
render_submit(view, :sign_in, %{})
|
||||
|
||||
assert [{"input", [_, _, {"type", "checkbox"}, {"value", "true"}], []}] =
|
||||
view
|
||||
|> render()
|
||||
|> Floki.parse_document!()
|
||||
|> Floki.find("#credentials_use_legacy_auth")
|
||||
|
||||
render_change(view, :validate, %{
|
||||
credentials: %{email: "$email", password: "$password", use_legacy_auth: true}
|
||||
})
|
||||
|
||||
render_submit(view, :sign_in, %{})
|
||||
|
||||
assert_receive {ApiMock,
|
||||
{:sign_in,
|
||||
%Credentials{email: "$email", password: "$password", use_legacy_auth: true}}}
|
||||
|
||||
assert_redirect(view, "/", 1000)
|
||||
end
|
||||
|
||||
test "offers to sign in via the legacy API if 2FA step failed", %{conn: conn, test: name} do
|
||||
params = start_api(name)
|
||||
|
||||
assert {:ok, view, _html} =
|
||||
conn
|
||||
|> put_connect_params(params)
|
||||
|> live("/sign_in")
|
||||
|
||||
render_change(view, :validate, %{credentials: %{email: "mfa", password: "$password"}})
|
||||
render_submit(view, :sign_in, %{})
|
||||
|
||||
assert_receive {ApiMock, {:sign_in, %Credentials{email: "mfa", password: "$password"}}}
|
||||
|
||||
assert [{"div", _, [{"select", [{"id", "mfa_device_id"} | _], _options}]}] =
|
||||
view
|
||||
|> render_change(:validate, %{mfa: %{device_id: "error", passcode: "999999"}})
|
||||
|> Floki.parse_document!()
|
||||
|> Floki.find(".is-loading")
|
||||
|
||||
assert_receive {ApiMock, {:sign_in, "error", "999999", %TeslaApi.Auth.MFA.Ctx{}}}
|
||||
|
||||
assert [{"button", _, [_icon, " ", {"span", _, ["Use legacy authentication API"]}]}] =
|
||||
view
|
||||
|> render()
|
||||
|> Floki.parse_document!()
|
||||
|> Floki.find("button[phx-click='use_legacy_login']")
|
||||
|
||||
assert [{"input", [_, _, {"type", "checkbox"}, {"value", "true"}, {"checked", "checked"}], _}] =
|
||||
view
|
||||
|> render_click(:use_legacy_login)
|
||||
|> Floki.parse_document!()
|
||||
|> Floki.find("#credentials_use_legacy_auth")
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user