Skip to content

Commit 5818707

Browse files
committed
feat: auto-join orgs by matching domain on signup
1 parent c30b7db commit 5818707

File tree

4 files changed

+81
-12
lines changed

4 files changed

+81
-12
lines changed

lib/algora/accounts/accounts.ex

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,47 @@ defmodule Algora.Accounts do
413413
params |> User.org_registration_changeset() |> Repo.insert()
414414
end
415415

416+
def auto_join_orgs(user) do
417+
domain = user.email |> String.split("@") |> List.last()
418+
419+
orgs =
420+
Repo.all(
421+
from o in User,
422+
left_join: m in Member,
423+
on: m.org_id == o.id and m.user_id == ^user.id,
424+
where: o.domain == ^domain and is_nil(m.id)
425+
)
426+
427+
Enum.each(orgs, fn org ->
428+
case Organizations.create_member(org, user, :mod) do
429+
{:ok, _member} ->
430+
Algora.Admin.alert("#{user.email} joined #{org.name}", :info)
431+
432+
{:error, _reason} ->
433+
Algora.Admin.alert("#{user.email} failed to join #{org.name}", :error)
434+
end
435+
end)
436+
437+
if org = List.first(orgs) do
438+
update_settings(user, %{last_context: org.handle})
439+
end
440+
441+
orgs
442+
end
443+
444+
def get_or_register_user(email) do
445+
res =
446+
case get_user_by_email(email) do
447+
nil -> register_org(%{email: email})
448+
user -> {:ok, user}
449+
end
450+
451+
with {:ok, user} <- res do
452+
auto_join_orgs(user)
453+
res
454+
end
455+
end
456+
416457
# def get_user_by_provider_email(provider, email) when provider in [:github] do
417458
# query =
418459
# from(u in User,

lib/algora_web/controllers/oauth_callback_controller.ex

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ defmodule AlgoraWeb.OAuthCallbackController do
6161

6262
def new(conn, %{"provider" => "email", "email" => email, "token" => token} = params) do
6363
with {:ok, _login_token} <- AlgoraWeb.UserAuth.verify_login_code(token, email),
64-
{:ok, user} <- get_or_register_user(email) do
64+
{:ok, user} <- Accounts.get_or_register_user(email) do
6565
conn =
6666
if params["return_to"] do
6767
put_session(conn, :user_return_to, String.trim_leading(params["return_to"], AlgoraWeb.Endpoint.url()))
@@ -90,11 +90,4 @@ defmodule AlgoraWeb.OAuthCallbackController do
9090
def sign_out(conn, _) do
9191
AlgoraWeb.UserAuth.log_out_user(conn)
9292
end
93-
94-
defp get_or_register_user(email) do
95-
case Accounts.get_user_by_email(email) do
96-
nil -> Accounts.register_org(%{email: email})
97-
user -> {:ok, user}
98-
end
99-
end
10093
end

lib/algora_web/live/org/dashboard_live.ex

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -783,10 +783,21 @@ defmodule AlgoraWeb.Org.DashboardLive do
783783
|> Ecto.Changeset.change(handle: handle, email: socket.assigns.email)
784784
|> Repo.update()
785785

786-
{:noreply,
787-
socket
788-
|> assign(:current_user, user)
789-
|> assign_achievements()}
786+
autojoined? =
787+
user
788+
|> Accounts.auto_join_orgs()
789+
|> Enum.any?(&(&1.id == socket.assigns.previewed_user.id))
790+
791+
socket =
792+
if autojoined? do
793+
switch_from_preview(socket, user)
794+
else
795+
socket
796+
|> assign(:current_user, user)
797+
|> assign_achievements()
798+
end
799+
800+
{:noreply, socket}
790801

791802
user ->
792803
socket = switch_from_preview(socket, user)

test/algora/accounts_test.exs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ defmodule Algora.AccountsTest do
55
alias Algora.Accounts.Identity
66
alias Algora.Accounts.User
77
alias Algora.Organizations
8+
alias Algora.Organizations.Member
89
alias Algora.Repo
910
alias Algora.Workspace.Repository
1011

@@ -164,6 +165,29 @@ defmodule Algora.AccountsTest do
164165
end
165166
end
166167

168+
describe "get_or_register_user/1" do
169+
test "auto-joins all orgs with matching domain" do
170+
org1 = insert(:organization, domain: "example.com")
171+
org2 = insert(:organization, domain: "example.com")
172+
173+
{:ok, user} = Accounts.get_or_register_user("[email protected]")
174+
175+
member1 = Repo.get_by(Member, user_id: user.id, org_id: org1.id)
176+
member2 = Repo.get_by(Member, user_id: user.id, org_id: org2.id)
177+
178+
assert not is_nil(member1)
179+
assert not is_nil(member2)
180+
end
181+
182+
test "does not auto-join org with non-matching domain" do
183+
org = insert(:organization, domain: "example.com")
184+
{:ok, user} = Accounts.get_or_register_user("[email protected]")
185+
186+
member = Repo.get_by(Member, user_id: user.id, org_id: org.id)
187+
assert is_nil(member)
188+
end
189+
end
190+
167191
describe "accounts" do
168192
test "query" do
169193
user_1 = insert(:user)

0 commit comments

Comments
 (0)