mirror of
https://github.com/plausible/analytics.git
synced 2024-12-23 09:33:19 +03:00
No longer require domain to seek Plugins API Tokens (#3409)
* No longer require domain to seek Plugins API Tokens * Accept raw token only
This commit is contained in:
parent
70c001099d
commit
99efb93082
@ -18,15 +18,14 @@ defmodule Plausible.Plugins.API.Tokens do
|
||||
end
|
||||
end
|
||||
|
||||
@spec find(String.t(), String.t()) :: {:ok, Token.t()} | {:error, :not_found}
|
||||
def find(domain, raw) do
|
||||
@spec find(String.t()) :: {:ok, Token.t()} | {:error, :not_found}
|
||||
def find(raw) do
|
||||
found =
|
||||
Repo.one(
|
||||
from(t in Token,
|
||||
inner_join: s in Site,
|
||||
on: s.id == t.site_id,
|
||||
where: t.token_hash == ^Token.hash(raw),
|
||||
where: s.domain == ^domain or s.domain_changed_from == ^domain,
|
||||
preload: [:site]
|
||||
)
|
||||
)
|
||||
|
@ -28,8 +28,9 @@ defmodule PlausibleWeb.Plugins.API.Spec do
|
||||
type: "http",
|
||||
scheme: "basic",
|
||||
description: """
|
||||
HTTP basic access authentication using your Site domain as the
|
||||
HTTP basic access authentication using your Site Domain as the
|
||||
username and the Plugins API Token contents as the password.
|
||||
Note that Site Domain is optional, a password alone suffices.
|
||||
|
||||
For more information see
|
||||
https://en.wikipedia.org/wiki/Basic_access_authentication
|
||||
|
@ -6,18 +6,19 @@ defmodule PlausibleWeb.Plugs.AuthorizePluginsAPI do
|
||||
|
||||
alias PlausibleWeb.Plugins.API.Errors
|
||||
alias Plausible.Plugins.API.Tokens
|
||||
import Plug.Conn
|
||||
|
||||
def init(opts), do: opts
|
||||
|
||||
def call(conn, _opts \\ []) do
|
||||
with {:ok, domain, token} <- extract_token(conn),
|
||||
{:ok, conn} <- authorize(conn, domain, token) do
|
||||
with {:ok, token} <- extract_token(conn),
|
||||
{:ok, conn} <- authorize(conn, token) do
|
||||
conn
|
||||
end
|
||||
end
|
||||
|
||||
defp authorize(conn, domain, token_value) do
|
||||
case Tokens.find(domain, token_value) do
|
||||
defp authorize(conn, token_value) do
|
||||
case Tokens.find(token_value) do
|
||||
{:ok, token} ->
|
||||
{:ok, Plug.Conn.assign(conn, :authorized_site, token.site)}
|
||||
|
||||
@ -27,11 +28,14 @@ defmodule PlausibleWeb.Plugs.AuthorizePluginsAPI do
|
||||
end
|
||||
|
||||
defp extract_token(conn) do
|
||||
case Plug.BasicAuth.parse_basic_auth(conn) do
|
||||
{token_identifier, token_value} ->
|
||||
{:ok, token_identifier, token_value}
|
||||
|
||||
:error ->
|
||||
with ["Basic " <> encoded_user_and_pass] <- get_req_header(conn, "authorization"),
|
||||
{:ok, decoded_user_and_pass} <- Base.decode64(encoded_user_and_pass) do
|
||||
case :binary.split(decoded_user_and_pass, ":") do
|
||||
[_user, token_value] -> {:ok, token_value}
|
||||
[token_value] -> {:ok, token_value}
|
||||
end
|
||||
else
|
||||
_ ->
|
||||
Errors.unauthorized(conn)
|
||||
end
|
||||
end
|
||||
|
@ -31,26 +31,13 @@ defmodule Plausible.Plugins.API.TokensTest do
|
||||
test "finds the right token" do
|
||||
site = insert(:site)
|
||||
assert {:ok, _, raw} = Tokens.create(site, "My test token")
|
||||
assert {:ok, found} = Tokens.find(site.domain, raw)
|
||||
assert {:ok, found} = Tokens.find(raw)
|
||||
assert found.id == found.id
|
||||
end
|
||||
|
||||
test "finds the right token after domain change" do
|
||||
site = insert(:site, domain: "foo1.example.com")
|
||||
assert {:ok, _, raw} = Tokens.create(site, "My test token")
|
||||
|
||||
{:ok, _} = Plausible.Site.Domain.change(site, "foo2.example.com")
|
||||
|
||||
assert {:ok, found} = Tokens.find("foo1.example.com", raw)
|
||||
assert {:ok, ^found} = Tokens.find("foo2.example.com", raw)
|
||||
assert found.site_id == site.id
|
||||
end
|
||||
|
||||
test "fails to find the token" do
|
||||
site = insert(:site)
|
||||
assert {:ok, _, _} = Tokens.create(site, "My test token")
|
||||
|
||||
assert {:error, :not_found} = Tokens.find(site.domain, "non-existing")
|
||||
assert {:error, :not_found} = Tokens.find("non-existing", "non-existing")
|
||||
assert {:error, :not_found} = Tokens.find("non-existing")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -21,6 +21,21 @@ defmodule PlausibleWeb.Plugs.AuthorizePluginsAPITest do
|
||||
assert %Plausible.Site{id: ^site_id} = conn.assigns.authorized_site
|
||||
end
|
||||
|
||||
test "plug passes when a token is found, no domain provided" do
|
||||
%{id: site_id} = site = insert(:site, domain: "pass.example.com")
|
||||
{:ok, _, raw} = Tokens.create(site, "Some token")
|
||||
|
||||
credentials = "Basic " <> Base.encode64(raw)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|> put_req_header("authorization", credentials)
|
||||
|> AuthorizePluginsAPI.call()
|
||||
|
||||
refute conn.halted
|
||||
assert %Plausible.Site{id: ^site_id} = conn.assigns.authorized_site
|
||||
end
|
||||
|
||||
test "plug halts when a token is not found" do
|
||||
site = insert(:site, domain: "pass.example.com")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user