From 7bc2583246564f1745f524ede2687e15eaafead0 Mon Sep 17 00:00:00 2001 From: michaeljguarino Date: Thu, 29 Aug 2024 13:07:09 -0400 Subject: [PATCH] Only allow oauth login against current login method There's probably a needed frontend change here too, but can handle that after the fact --- apps/core/lib/core/schema/account.ex | 2 ++ apps/core/lib/core/schema/validations.ex | 16 ++++++++++++++++ apps/core/lib/core/services/users.ex | 3 ++- apps/core/test/services/accounts_test.exs | 6 +++++- apps/core/test/services/users_test.exs | 8 +++++++- 5 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 apps/core/lib/core/schema/validations.ex diff --git a/apps/core/lib/core/schema/account.ex b/apps/core/lib/core/schema/account.ex index 00de4607b..0fd97ecc4 100644 --- a/apps/core/lib/core/schema/account.ex +++ b/apps/core/lib/core/schema/account.ex @@ -1,6 +1,7 @@ defmodule Core.Schema.Account do use Piazza.Ecto.Schema use Arc.Ecto.Schema + import Core.Schema.Validations alias Core.Schema.{User, DomainMapping, PlatformSubscription, Address} schema "accounts" do @@ -64,6 +65,7 @@ defmodule Core.Schema.Account do |> generate_uuid(:icon_id) |> cast_attachments(attrs, [:icon], allow_urls: true) |> set_address_updated() + |> reject_urls(:name) end diff --git a/apps/core/lib/core/schema/validations.ex b/apps/core/lib/core/schema/validations.ex new file mode 100644 index 000000000..db353e1a6 --- /dev/null +++ b/apps/core/lib/core/schema/validations.ex @@ -0,0 +1,16 @@ +defmodule Core.Schema.Validations do + import Ecto.Changeset + + @url_regex ~r/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&\/\/=]*)/ + + def reject_urls(cs, field) do + validate_change(cs, field, fn + _, val when is_binary(val) -> + case String.match?(val, @url_regex) do + true -> [{field, "cannot contain urls"}] + _ -> [] + end + _, _ -> [{field, "must be a string"}] + end) + end +end diff --git a/apps/core/lib/core/services/users.ex b/apps/core/lib/core/services/users.ex index 6a1041bdf..d01a9978c 100644 --- a/apps/core/lib/core/services/users.ex +++ b/apps/core/lib/core/services/users.ex @@ -373,8 +373,9 @@ defmodule Core.Services.Users do |> Map.merge(login_args(service)) |> Map.put(:password, Ecto.UUID.generate()) |> create_user() - %User{} = user -> + %User{login_method: ^service} = user -> update_user(login_args(service), user) + _ -> {:error, "you don't have login with #{service} enabled"} end end diff --git a/apps/core/test/services/accounts_test.exs b/apps/core/test/services/accounts_test.exs index 01b174994..5b5b30f7b 100644 --- a/apps/core/test/services/accounts_test.exs +++ b/apps/core/test/services/accounts_test.exs @@ -147,6 +147,10 @@ defmodule Core.Services.AccountsTest do assert account.name == "updated" end + test "cannot put urls in names", %{user: user} do + {:error, _} = Accounts.update_account(%{name: "https://evil.com"}, user) + end + test "if billing address is updated, it will update the stripe customer", %{user: user, account: account} do {:ok, _} = update_record(account, %{billing_customer_id: "strp"}) me = self() @@ -335,7 +339,7 @@ defmodule Core.Services.AccountsTest do assert invite.user_id == user.id end - test "nonroot users can create group members", %{account: account} do + test "nonroot users cannot create group members", %{account: account} do {:error, _} = Accounts.create_invite(%{email: "some@example.com"}, insert(:user, account: account)) end end diff --git a/apps/core/test/services/users_test.exs b/apps/core/test/services/users_test.exs index 4fe281ee6..8caa07b93 100644 --- a/apps/core/test/services/users_test.exs +++ b/apps/core/test/services/users_test.exs @@ -524,13 +524,19 @@ defmodule Core.Services.UsersTest do end test "it will update login method for existing users" do - user = insert(:user) + user = insert(:user, login_method: :google) {:ok, upd} = Users.bootstrap_user(:google, %{email: user.email}) assert upd.id == user.id assert upd.login_method == :google end + + test "it will not allow logins w/o login method set" do + user = insert(:user) + + {:error, _} = Users.bootstrap_user(:google, %{email: user.email}) + end end describe "#create_trust_relationship" do