Include username and email in ID token
This commit is contained in:
parent
13461897b4
commit
4490cd6a04
7 changed files with 43 additions and 5 deletions
|
@ -4,6 +4,7 @@ defmodule Comfycamp.Accounts.User do
|
||||||
|
|
||||||
schema "users" do
|
schema "users" do
|
||||||
field :email, :string
|
field :email, :string
|
||||||
|
field :username, :string
|
||||||
field :password, :string, virtual: true, redact: true
|
field :password, :string, virtual: true, redact: true
|
||||||
field :hashed_password, :string, redact: true
|
field :hashed_password, :string, redact: true
|
||||||
field :confirmed_at, :naive_datetime
|
field :confirmed_at, :naive_datetime
|
||||||
|
@ -39,9 +40,11 @@ defmodule Comfycamp.Accounts.User do
|
||||||
"""
|
"""
|
||||||
def registration_changeset(user, attrs, opts \\ []) do
|
def registration_changeset(user, attrs, opts \\ []) do
|
||||||
user
|
user
|
||||||
|> cast(attrs, [:email, :password, :info])
|
|> cast(attrs, [:email, :username, :password, :info])
|
||||||
|> validate_email(opts)
|
|> validate_email(opts)
|
||||||
|
|> validate_username(opts)
|
||||||
|> validate_password(opts)
|
|> validate_password(opts)
|
||||||
|
|> validate_required([:info])
|
||||||
|> validate_length(:info, min: 2, max: 4096)
|
|> validate_length(:info, min: 2, max: 4096)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -53,6 +56,15 @@ defmodule Comfycamp.Accounts.User do
|
||||||
|> maybe_validate_unique_email(opts)
|
|> maybe_validate_unique_email(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp validate_username(changeset, _opts) do
|
||||||
|
changeset
|
||||||
|
|> validate_required([:username])
|
||||||
|
|> validate_format(:username, ~r/^[A-Za-z0-9\.\-_]+$/,
|
||||||
|
message: "можно использовать английский алфавит, цифры и некоторые символы"
|
||||||
|
)
|
||||||
|
|> validate_length(:username, min: 2, max: 64)
|
||||||
|
end
|
||||||
|
|
||||||
defp validate_password(changeset, opts) do
|
defp validate_password(changeset, opts) do
|
||||||
changeset
|
changeset
|
||||||
|> validate_required([:password])
|
|> validate_required([:password])
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
defmodule Comfycamp.SSO.IDToken do
|
defmodule Comfycamp.SSO.IDToken do
|
||||||
@derive Jason.Encoder
|
@derive Jason.Encoder
|
||||||
defstruct [:iss, :sub, :aud, :exp, :iat]
|
defstruct [:iss, :sub, :aud, :exp, :iat, :email, :preferred_username]
|
||||||
|
|
||||||
def build_id_token(user, client_id) do
|
def build_id_token(user, client_id) do
|
||||||
{_, now} = DateTime.now("Etc/UTC")
|
{_, now} = DateTime.now("Etc/UTC")
|
||||||
|
@ -16,7 +16,9 @@ defmodule Comfycamp.SSO.IDToken do
|
||||||
sub: Integer.to_string(user.id),
|
sub: Integer.to_string(user.id),
|
||||||
aud: client_id,
|
aud: client_id,
|
||||||
exp: expires_at,
|
exp: expires_at,
|
||||||
iat: issued_at
|
iat: issued_at,
|
||||||
|
email: user.email,
|
||||||
|
preferred_username: user.username
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,6 +9,7 @@ defmodule ComfycampWeb.UserEditorHTML do
|
||||||
<tr>
|
<tr>
|
||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Email</th>
|
<th>Email</th>
|
||||||
|
<th>Username</th>
|
||||||
<th>Одобрен?</th>
|
<th>Одобрен?</th>
|
||||||
<th>Админ?</th>
|
<th>Админ?</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
@ -18,6 +19,7 @@ defmodule ComfycampWeb.UserEditorHTML do
|
||||||
<td>
|
<td>
|
||||||
<.link href={~p"/admin/users/#{user}"}><%= user.email %></.link>
|
<.link href={~p"/admin/users/#{user}"}><%= user.email %></.link>
|
||||||
</td>
|
</td>
|
||||||
|
<td><%= user.username %></td>
|
||||||
<td><%= user.is_approved %></td>
|
<td><%= user.is_approved %></td>
|
||||||
<td><%= user.is_admin %></td>
|
<td><%= user.is_admin %></td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -32,6 +32,7 @@ defmodule ComfycampWeb.UserRegistrationLive do
|
||||||
</.error>
|
</.error>
|
||||||
|
|
||||||
<.input field={@form[:email]} type="email" label="Email" required />
|
<.input field={@form[:email]} type="email" label="Email" required />
|
||||||
|
<.input field={@form[:username]} type="text" label="Логин" required />
|
||||||
<.input field={@form[:password]} type="password" label="Пароль" required />
|
<.input field={@form[:password]} type="password" label="Пароль" required />
|
||||||
<.input
|
<.input
|
||||||
field={@form[:info]}
|
field={@form[:info]}
|
||||||
|
|
18
priv/repo/migrations/20241005121850_add_usernames.exs
Normal file
18
priv/repo/migrations/20241005121850_add_usernames.exs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
defmodule Comfycamp.Repo.Migrations.AddUsernames do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:users) do
|
||||||
|
add :username, :citext
|
||||||
|
end
|
||||||
|
|
||||||
|
execute("""
|
||||||
|
UPDATE users
|
||||||
|
SET username = email
|
||||||
|
""")
|
||||||
|
|
||||||
|
alter table(:users) do
|
||||||
|
modify :username, :citext, null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -97,7 +97,7 @@ defmodule Comfycamp.AccountsTest do
|
||||||
describe "change_user_registration/2" do
|
describe "change_user_registration/2" do
|
||||||
test "returns a changeset" do
|
test "returns a changeset" do
|
||||||
assert %Ecto.Changeset{} = changeset = Accounts.change_user_registration(%User{})
|
assert %Ecto.Changeset{} = changeset = Accounts.change_user_registration(%User{})
|
||||||
assert changeset.required == [:password, :email]
|
assert changeset.required == [:info, :password, :username, :email]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "allows fields to be set" do
|
test "allows fields to be set" do
|
||||||
|
|
|
@ -5,12 +5,15 @@ defmodule Comfycamp.AccountsFixtures do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def unique_user_email, do: "user#{System.unique_integer()}@example.com"
|
def unique_user_email, do: "user#{System.unique_integer()}@example.com"
|
||||||
|
def unique_username, do: "user#{System.unique_integer()}"
|
||||||
def valid_user_password, do: "hello world!"
|
def valid_user_password, do: "hello world!"
|
||||||
|
|
||||||
def valid_user_attributes(attrs \\ %{}) do
|
def valid_user_attributes(attrs \\ %{}) do
|
||||||
Enum.into(attrs, %{
|
Enum.into(attrs, %{
|
||||||
email: unique_user_email(),
|
email: unique_user_email(),
|
||||||
password: valid_user_password()
|
username: unique_username(),
|
||||||
|
password: valid_user_password(),
|
||||||
|
info: "hello world!"
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue