Add unique constraint to api keys (#2931)

* Add unique constraint to api keys

* Fix test

* Remove `user_id` from api key index
This commit is contained in:
Uku Taht 2023-05-23 11:37:58 +03:00 committed by GitHub
parent 3482337348
commit ca3e2e5121
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 3 deletions

View File

@ -24,6 +24,7 @@ defmodule Plausible.Auth.ApiKey do
|> validate_required(@required)
|> generate_key()
|> process_key()
|> unique_constraint(:key_hash, error_key: :key)
end
def update(schema, attrs \\ %{}) do

View File

@ -11,9 +11,10 @@
<%= label f, :key, class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
<div class="relative mt-1">
<%= text_input f, :key, id: "key-input", class: "dark:text-gray-300 shadow-sm bg-gray-50 dark:bg-gray-850 focus:ring-indigo-500 focus:border-indigo-500 block w-full sm:text-sm border-gray-300 dark:border-gray-500 rounded-md pr-16", readonly: "readonly" %>
<a onclick="var textarea = document.getElementById('key-input'); textarea.focus(); textarea.select(); document.execCommand('copy');" href="javascript:void(0)" class="absolute flex items-center text-xs font-medium text-indigo-600 no-underline hover:underline" style="top: 12px; right: 12px;">
<svg class="pr-1 text-indigo-600 dark:text-indigo-500" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>COPY
</a>
<a onclick="var textarea = document.getElementById('key-input'); textarea.focus(); textarea.select(); document.execCommand('copy');" href="javascript:void(0)" class="absolute flex items-center text-xs font-medium text-indigo-600 no-underline hover:underline" style="top: 12px; right: 12px;">
<svg class="pr-1 text-indigo-600 dark:text-indigo-500" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>COPY
</a>
<%= error_tag f, :key %>
<p class="mt-2 text-sm text-gray-500 dark:text-gray-200">Make sure to store the key in a secure place. Once created, we will not be able to show it again.</p>
</div>
</div>

View File

@ -0,0 +1,7 @@
defmodule Plausible.Repo.Migrations.AddUniqueIndexToApiKeys do
use Ecto.Migration
def change do
create unique_index(:api_keys, :key_hash)
end
end

View File

@ -709,6 +709,49 @@ defmodule PlausibleWeb.AuthControllerTest do
setup [:create_user, :log_in]
import Ecto.Query
test "can create an API key", %{conn: conn, user: user} do
site = insert(:site)
insert(:site_membership, site: site, user: user, role: "owner")
conn =
post(conn, "/settings/api-keys", %{
"api_key" => %{
"user_id" => user.id,
"name" => "all your code are belong to us",
"key" => "swordfish"
}
})
key = Plausible.Auth.ApiKey |> where(user_id: ^user.id) |> Repo.one()
assert conn.status == 302
assert key.name == "all your code are belong to us"
end
test "cannot create a duplicate API key", %{conn: conn, user: user} do
site = insert(:site)
insert(:site_membership, site: site, user: user, role: "owner")
conn =
post(conn, "/settings/api-keys", %{
"api_key" => %{
"user_id" => user.id,
"name" => "all your code are belong to us",
"key" => "swordfish"
}
})
conn2 =
post(conn, "/settings/api-keys", %{
"api_key" => %{
"user_id" => user.id,
"name" => "all your code are belong to us",
"key" => "swordfish"
}
})
assert html_response(conn2, 200) =~ "has already been taken"
end
test "can't create api key into another site", %{conn: conn, user: me} do
my_site = insert(:site)
insert(:site_membership, site: my_site, user: me, role: "owner")