Add api keys to CRM

This commit is contained in:
Uku Taht 2021-06-10 10:25:19 +03:00
parent 0a3623b07f
commit 0054c9fc96
4 changed files with 68 additions and 23 deletions

View File

@ -41,22 +41,4 @@ config :plausible, :user_agent_cache,
limit: 1000,
stats: false
config :kaffy,
otp_app: :plausible,
ecto_repo: Plausible.Repo,
router: PlausibleWeb.Router,
admin_title: "Plausible Admin",
resources: [
auth: [
resources: [
user: [schema: Plausible.Auth.User, admin: Plausible.Auth.UserAdmin]
]
],
sites: [
resources: [
site: [schema: Plausible.Site, admin: Plausible.SiteAdmin]
]
]
]
import_config "#{config_env()}.exs"

View File

@ -279,7 +279,8 @@ config :kaffy,
resources: [
auth: [
resources: [
user: [schema: Plausible.Auth.User, admin: Plausible.Auth.UserAdmin]
user: [schema: Plausible.Auth.User, admin: Plausible.Auth.UserAdmin],
api_key: [schema: Plausible.Auth.ApiKey, admin: Plausible.Auth.ApiKeyAdmin]
]
],
sites: [

View File

@ -2,12 +2,12 @@ defmodule Plausible.Auth.ApiKey do
use Ecto.Schema
import Ecto.Changeset
@required [:user_id, :key, :name]
@optional [:scopes, :hourly_request_limit]
@required [:user_id, :name]
@optional [:key, :scopes, :hourly_request_limit]
schema "api_keys" do
field :name, :string
field :scopes, {:array, :string}, default: ["stats:read:*"]
field :hourly_request_limit, :integer
field :hourly_request_limit, :integer, default: 1000
field :key, :string, virtual: true
field :key_hash, :string
@ -22,7 +22,14 @@ defmodule Plausible.Auth.ApiKey do
schema
|> cast(attrs, @required ++ @optional)
|> validate_required(@required)
|> process_key
|> generate_key()
|> process_key()
end
def update(schema, attrs \\ %{}) do
schema
|> cast(attrs, [:name, :user_id, :scopes, :hourly_request_limit])
|> validate_required([:user_id, :name])
end
def do_hash(key) do
@ -42,6 +49,15 @@ defmodule Plausible.Auth.ApiKey do
def process_key(changeset), do: changeset
defp generate_key(changeset) do
if !changeset.changes[:key] do
key = :crypto.strong_rand_bytes(64) |> Base.url_encode64() |> binary_part(0, 64)
change(changeset, key: key)
else
changeset
end
end
defp secret_key_base() do
Application.get_env(:plausible, PlausibleWeb.Endpoint)
|> Keyword.fetch!(:secret_key_base)

View File

@ -0,0 +1,46 @@
defmodule Plausible.Auth.ApiKeyAdmin do
use Plausible.Repo
def search_fields(_schema) do
[
:name,
user: [:name, :email]
]
end
def custom_index_query(_conn, _schema, query) do
from(r in query, preload: [:user])
end
def create_changeset(schema, attrs) do
scopes = [attrs["scope"]]
Plausible.Auth.ApiKey.changeset(schema, Map.merge(%{"scopes" => scopes}, attrs))
end
def update_changeset(schema, attrs) do
Plausible.Auth.ApiKey.update(schema, attrs) |> IO.inspect()
end
@plaintext_key_help """
The value of the API key is sensitive data like a password. Once created, the value of they will never be revealed again. Make sure to copy/paste this into a secure place before hitting 'save'. When sending the key to a customer, use a secure E2EE system that destructs the message after a certain period like https://bitwarden.com/products/send
"""
def form_fields(_) do
[
name: nil,
key: %{create: :readonly, update: :hidden, help_text: @plaintext_key_help},
key_prefix: %{create: :hidden, update: :readonly},
hourly_request_limit: %{default: 1000},
scope: %{choices: [{"Stats API", ["stats:read:*"]}, {"Sites API", ["sites:provision:*"]}]},
user_id: nil
]
end
def index(_) do
[
key_prefix: nil,
name: nil,
scopes: nil,
owner: %{value: & &1.user.email}
]
end
end