Skip to content

Commit

Permalink
make Credentials unique by user by name (#2371)
Browse files Browse the repository at this point in the history
* ref #2367, make creds unique by user by name

* update cl

* use random cred name
  • Loading branch information
taylordowns2000 authored Aug 13, 2024
1 parent a4b8645 commit 4ee43fa
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ and this project adheres to

### Changed

- Enforced uniqueness on credential names _by user_.
[#2371](https://github.com/OpenFn/lightning/pull/2371)
- Use Swoosh to format User models into recipients
[#2374](https://github.com/OpenFn/lightning/pull/2374)

Expand Down
3 changes: 3 additions & 0 deletions lib/lightning/credentials/credential.ex
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ defmodule Lightning.Credentials.Credential do
])
|> cast_assoc(:project_credentials)
|> validate_required([:name, :body, :user_id])
|> unique_constraint([:name, :user_id],
message: "you have another credential with the same name"
)
|> assoc_constraint(:user)
|> assoc_constraint(:oauth_client)
|> validate_oauth()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
defmodule Lightning.Repo.Migrations.AddUniquenessToCredentialNamePerUser do
use Ecto.Migration

def up do
# Identify duplicates and update them to ensure uniqueness
execute """
WITH duplicates AS (
SELECT
id,
name,
user_id,
ROW_NUMBER() OVER (PARTITION BY LOWER(REPLACE(name, '-', ' ')), user_id ORDER BY id) AS row_num
FROM
credentials
)
UPDATE credentials
SET name = credentials.name || '-' || duplicates.row_num
FROM duplicates
WHERE credentials.id = duplicates.id
AND duplicates.row_num > 1;
"""

execute """
CREATE UNIQUE INDEX credentials_name_user_id_index ON credentials (LOWER(REPLACE(name, '-', ' ')), user_id);
"""
end

def down do
execute """
DROP INDEX credentials_name_user_id_index;
"""
end
end
1 change: 1 addition & 0 deletions test/lightning/accounts_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ defmodule Lightning.AccountsTest do

CredentialsFixtures.project_credential_fixture(user_id: user.id, name: "a")
CredentialsFixtures.project_credential_fixture(user_id: user.id, name: "b")

CredentialsFixtures.project_credential_fixture()

assert count_project_credentials_for_user(user) == 2
Expand Down
25 changes: 25 additions & 0 deletions test/lightning/credentials_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,31 @@ defmodule Lightning.CredentialsTest do
end

describe "create_credential/1" do
test "fails if another cred exists with the same name for the same user" do
valid_attrs = %{
body: %{"a" => "test"},
name: "simple name",
user_id: insert(:user).id,
schema: "raw"
}

assert {:ok, %Credential{}} = Credentials.create_credential(valid_attrs)

assert {
:error,
%Ecto.Changeset{
errors: [
name:
{"you have another credential with the same name",
[
constraint: :unique,
constraint_name: "credentials_name_user_id_index"
]}
]
}
} = Credentials.create_credential(valid_attrs)
end

test "suceeds with raw schema" do
valid_attrs = %{
body: %{"username" => "user", "password" => "pass", "port" => 5000},
Expand Down
2 changes: 1 addition & 1 deletion test/lightning_web/live/project_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ defmodule LightningWeb.ProjectLiveTest do
"#credentials"
)

credential_name = "My Credential"
credential_name = Lightning.Name.generate()

refute html =~ credential_name

Expand Down

0 comments on commit 4ee43fa

Please sign in to comment.