Skip to content

Commit eef3e21

Browse files
authored
fix(guard): use correct field for generating service account email domains (#523)
1 parent 9b2ea5a commit eef3e21

File tree

7 files changed

+31
-25
lines changed

7 files changed

+31
-25
lines changed

guard/lib/guard/front_repo/user.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,9 @@ defmodule Guard.FrontRepo.User do
272272
|> validate_length(:name, max: 255, message: "Name cannot exceed 255 characters")
273273
|> validate_inclusion(:creation_source, [:service_account])
274274
|> put_change(:single_org_user, true)
275-
|> validate_format(:email, ~r/^[\w\-\.]+@service_accounts\.[\w\-\.]+\.#{escaped_domain}$/i,
275+
|> validate_format(:email, ~r/^[\w\-\.]+@service-accounts\.[\w\-\.]+\.#{escaped_domain}$/i,
276276
message:
277-
"Service account email must follow the format: name@service_accounts.organization.#{base_domain}"
277+
"Service account email must follow the format: name@service-accounts.organization.#{base_domain}"
278278
)
279279
|> unique_constraint(:email, name: :index_users_on_email)
280280
|> unique_constraint(:authentication_token, name: :index_users_on_authentication_token)
@@ -290,7 +290,7 @@ defmodule Guard.FrontRepo.User do
290290
sanitized_org_name = sanitize_email_part(organization_name)
291291
base_domain = Application.fetch_env!(:guard, :base_domain)
292292

293-
"#{sanitized_sa_name}@service_accounts.#{sanitized_org_name}.#{base_domain}"
293+
"#{sanitized_sa_name}@service-accounts.#{sanitized_org_name}.#{base_domain}"
294294
end
295295

296296
defp sanitize_email_part(name) do

guard/lib/guard/store/service_account.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -510,20 +510,20 @@ defmodule Guard.Store.ServiceAccount do
510510
base_domain = Application.fetch_env!(:guard, :base_domain)
511511

512512
case Guard.Api.Organization.fetch(org_id) do
513-
%{username: org_username} ->
513+
%{org_username: org_username} ->
514514
# Sanitize names for email compatibility
515515
sanitized_name =
516516
String.downcase(service_account_name) |> String.replace(~r/[^a-z0-9\-]/, "-")
517517

518518
sanitized_org = String.downcase(org_username) |> String.replace(~r/[^a-z0-9\-]/, "-")
519-
"#{sanitized_name}@service_accounts.#{sanitized_org}.#{base_domain}"
519+
"#{sanitized_name}@service-accounts.#{sanitized_org}.#{base_domain}"
520520

521521
_ ->
522522
# Fallback if org not found (shouldn't happen in normal flow)
523523
sanitized_name =
524524
String.downcase(service_account_name) |> String.replace(~r/[^a-z0-9\-]/, "-")
525525

526-
"#{sanitized_name}@service_accounts.unknown.#{base_domain}"
526+
"#{sanitized_name}@service-accounts.unknown.#{base_domain}"
527527
end
528528
end
529529

guard/test/guard/grpc_servers/user_server_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1386,7 +1386,7 @@ defmodule Guard.GrpcServers.UserServerTest do
13861386
assert user_id == user.id
13871387
assert user_email == user.email
13881388
assert user_name == user.name
1389-
assert String.contains?(user_email, "@service_accounts.")
1389+
assert String.contains?(user_email, "@service-accounts.")
13901390
assert String.contains?(user_email, ".#{Application.fetch_env!(:guard, :base_domain)}")
13911391
end
13921392

guard/test/guard/service_account/actions_test.exs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ defmodule Guard.ServiceAccount.ActionsTest do
9393
creator_id: "creator-id",
9494
deactivated: false,
9595
email:
96-
"test@service_accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
96+
"test@service-accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
9797
},
9898
api_token: "test-token"
9999
}}
@@ -105,7 +105,7 @@ defmodule Guard.ServiceAccount.ActionsTest do
105105
assert user_id == "user-id"
106106

107107
assert email ==
108-
"test@service_accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
108+
"test@service-accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
109109

110110
assert name == "Test SA"
111111
:ok
@@ -124,7 +124,7 @@ defmodule Guard.ServiceAccount.ActionsTest do
124124
assert_called(
125125
Guard.Store.RbacUser.create(
126126
"user-id",
127-
"test@service_accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}",
127+
"test@service-accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}",
128128
"Test SA",
129129
"service_account"
130130
)
@@ -366,7 +366,8 @@ defmodule Guard.ServiceAccount.ActionsTest do
366366
describe "integration tests" do
367367
defp setup_integration_mocks do
368368
[
369-
{Guard.Api.Organization, [:passthrough], [fetch: fn _ -> %{username: "test-org"} end]},
369+
{Guard.Api.Organization, [:passthrough],
370+
[fetch: fn _ -> %InternalApi.Organization.Organization{org_username: "test-org"} end]},
370371
{Guard.FrontRepo.User, [:passthrough],
371372
[reset_auth_token: fn _ -> {:ok, "test-token"} end]},
372373
{Guard.Store.RbacUser, [:passthrough],
@@ -398,7 +399,7 @@ defmodule Guard.ServiceAccount.ActionsTest do
398399

399400
assert String.contains?(
400401
service_account.email,
401-
"@service_accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
402+
"@service-accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
402403
)
403404

404405
# Verify event was published

guard/test/guard/store/service_account_test.exs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,8 @@ defmodule Guard.Store.ServiceAccountTest do
205205
describe "create/1" do
206206
test "creates service account successfully" do
207207
with_mocks([
208-
{Guard.Api.Organization, [:passthrough], [fetch: fn _ -> %{username: "test-org"} end]},
208+
{Guard.Api.Organization, [:passthrough],
209+
[fetch: fn _ -> %InternalApi.Organization.Organization{org_username: "test-org"} end]},
209210
{Guard.FrontRepo.User, [:passthrough],
210211
[reset_auth_token: fn _ -> {:ok, "plain-token"} end]}
211212
]) do
@@ -222,14 +223,15 @@ defmodule Guard.Store.ServiceAccountTest do
222223

223224
assert String.contains?(
224225
result.service_account.email,
225-
"@service_accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
226+
"@service-accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
226227
)
227228
end
228229
end
229230

230231
test "creates user with correct service account fields" do
231232
with_mocks([
232-
{Guard.Api.Organization, [:passthrough], [fetch: fn _ -> %{username: "test-org"} end]},
233+
{Guard.Api.Organization, [:passthrough],
234+
[fetch: fn _ -> %InternalApi.Organization.Organization{org_username: "test-org"} end]},
233235
{Guard.FrontRepo.User, [:passthrough],
234236
[reset_auth_token: fn _ -> {:ok, "plain-token"} end]}
235237
]) do
@@ -253,17 +255,18 @@ defmodule Guard.Store.ServiceAccountTest do
253255

254256
test "generates synthetic email correctly" do
255257
with_mocks([
256-
{Guard.Api.Organization, [:passthrough], [fetch: fn _ -> %{username: "MyOrg-123"} end]},
258+
{Guard.Api.Organization, [:passthrough],
259+
[fetch: fn _ -> %InternalApi.Organization.Organization{org_username: "MyOrg-123"} end]},
257260
{Guard.FrontRepo.User, [:passthrough],
258261
[reset_auth_token: fn _ -> {:ok, "plain-token"} end]}
259262
]) do
260263
params = ServiceAccountFactory.build_params_with_creator(name: "My Service Account!")
261264

262265
{:ok, result} = ServiceAccount.create(params)
263266

264-
# Should sanitize both name and org username
267+
# Should sanitize both name and org org_username
265268
assert result.service_account.email ==
266-
"my-service-account-@service_accounts.myorg-123.#{Application.fetch_env!(:guard, :base_domain)}"
269+
"my-service-account-@service-accounts.myorg-123.#{Application.fetch_env!(:guard, :base_domain)}"
267270
end
268271
end
269272

@@ -280,7 +283,7 @@ defmodule Guard.Store.ServiceAccountTest do
280283
# Should use fallback email
281284
assert String.contains?(
282285
result.service_account.email,
283-
"@service_accounts.unknown.#{Application.fetch_env!(:guard, :base_domain)}"
286+
"@service-accounts.unknown.#{Application.fetch_env!(:guard, :base_domain)}"
284287
)
285288
end
286289
end
@@ -298,7 +301,8 @@ defmodule Guard.Store.ServiceAccountTest do
298301

299302
test "handles user creation validation errors" do
300303
with_mocks([
301-
{Guard.Api.Organization, [:passthrough], [fetch: fn _ -> %{username: "test-org"} end]},
304+
{Guard.Api.Organization, [:passthrough],
305+
[fetch: fn _ -> %InternalApi.Organization.Organization{org_username: "test-org"} end]},
302306
{Guard.FrontRepo.User, [:passthrough],
303307
[reset_auth_token: fn _ -> {:ok, "plain-token"} end]}
304308
]) do
@@ -326,7 +330,8 @@ defmodule Guard.Store.ServiceAccountTest do
326330
end
327331

328332
test "updates synthetic email when name changes" do
329-
with_mock Guard.Api.Organization, [:passthrough], fetch: fn _ -> %{username: "test-org"} end do
333+
with_mock Guard.Api.Organization, [:passthrough],
334+
fetch: fn _ -> %InternalApi.Organization.Organization{org_username: "test-org"} end do
330335
{:ok, %{service_account: sa}} = ServiceAccountFactory.insert()
331336

332337
update_params = %{name: "New Name"}
@@ -337,7 +342,7 @@ defmodule Guard.Store.ServiceAccountTest do
337342

338343
assert String.contains?(
339344
updated_sa.user.email,
340-
"new-name@service_accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
345+
"new-name@service-accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
341346
)
342347
end
343348
end

guard/test/guard/user/actions_test.exs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ defmodule Guard.User.ActionsTest do
134134
test "should not allow creating regular user with service account email pattern" do
135135
with_mock Guard.Events.UserCreated, publish: fn _, _ -> :ok end do
136136
base_domain = Application.fetch_env!(:guard, :base_domain)
137-
service_email = "test@service_accounts.org.#{base_domain}"
137+
service_email = "test@service-accounts.org.#{base_domain}"
138138

139139
user_params = %{
140140
email: service_email,
@@ -164,7 +164,7 @@ defmodule Guard.User.ActionsTest do
164164
assert updated_user.name == "Updated SA Name"
165165
assert updated_user.creation_source == :service_account
166166
assert updated_user.single_org_user == true
167-
assert String.contains?(updated_user.email, "@service_accounts.")
167+
assert String.contains?(updated_user.email, "@service-accounts.")
168168
end
169169
end
170170

guard/test/support/factories/service_account_factory.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ defmodule Support.Factories.ServiceAccountFactory do
109109

110110
defp generate_synthetic_email(name, _org_id) do
111111
sanitized_name = String.downcase(name) |> String.replace(~r/[^a-z0-9\-]/, "-")
112-
"#{sanitized_name}@service_accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
112+
"#{sanitized_name}@service-accounts.test-org.#{Application.fetch_env!(:guard, :base_domain)}"
113113
end
114114

115115
defp get_role_id(nil), do: UUID.generate()

0 commit comments

Comments
 (0)