Skip to content

Commit

Permalink
Add utility function to load credentials with oauth fields when neces…
Browse files Browse the repository at this point in the history
…sary
  • Loading branch information
elias-ba committed Feb 25, 2025
1 parent df3a1a7 commit c4cfe1b
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 58 deletions.
61 changes: 19 additions & 42 deletions lib/lightning/credentials.ex
Original file line number Diff line number Diff line change
Expand Up @@ -70,66 +70,43 @@ defmodule Lightning.Credentials do
Retrieves all credentials based on the given context, either a Project or a User.
## Parameters
- context: The Project or User struct to retrieve credentials for.
## Returns
- A list of credentials associated with the given Project or created by the given User.
## Examples
When given a Project:
iex> list_credentials(%Project{id: 1})
[%Credential{project_id: 1}, %Credential{project_id: 1}]
When given a User:
iex> list_credentials(%User{id: 123})
[%Credential{user_id: 123}, %Credential{user_id: 123}]
"""
@spec list_credentials(%Project{}) :: [%Credential{}]
def list_credentials(%Project{} = project) do
credentials =
Ecto.assoc(project, :credentials)
|> preload([
:user,
:project_credentials,
:projects,
oauth_token: :oauth_client
])
|> Repo.all()

# Set virtual fields for each credential
Enum.map(credentials, &set_oauth_virtual_fields/1)
Ecto.assoc(project, :credentials)
|> preload([
:user,
:project_credentials,
:projects,
oauth_token: :oauth_client
])
|> Repo.all()
|> Enum.map(&Credential.with_oauth/1)
end

@spec list_credentials(%User{id: integer()}) :: [%Credential{}]
def list_credentials(%User{id: user_id}) do
credentials =
from(c in Credential,
where: c.user_id == ^user_id,
preload: [:projects, :user, oauth_token: :oauth_client]
)
|> Repo.all()

# Set virtual fields for each credential
Enum.map(credentials, &set_oauth_virtual_fields/1)
end

defp set_oauth_virtual_fields(%Credential{} = credential) do
if Ecto.assoc_loaded?(credential.oauth_token) && credential.oauth_token do
# Update both body and virtual fields for all credentials with oauth_token
%{
credential
| body: credential.oauth_token.body,
oauth_client_id: credential.oauth_token.oauth_client_id,
oauth_client:
if(Ecto.assoc_loaded?(credential.oauth_token.oauth_client),
do: credential.oauth_token.oauth_client,
else: nil
)
}
else
credential
end
from(c in Credential,
where: c.user_id == ^user_id,
preload: [:projects, :user, oauth_token: :oauth_client]
)
|> Repo.all()
|> Enum.map(&Credential.with_oauth/1)
end

@doc """
Expand Down
51 changes: 35 additions & 16 deletions lib/lightning/credentials/credential.ex
Original file line number Diff line number Diff line change
Expand Up @@ -59,26 +59,45 @@ defmodule Lightning.Credentials.Credential do
end

@doc """
Gets the oauth_client_id for a credential by checking its oauth_token.
"""
def oauth_client_id(%__MODULE__{oauth_token: %OauthToken{oauth_client_id: id}}),
do: id
Transforms a credential by copying OAuth token fields to the credential struct.
def oauth_client_id(%__MODULE__{} = credential) do
credential = Lightning.Repo.preload(credential, :oauth_token)
oauth_client_id(credential)
end
For OAuth credentials with an associated token, this function copies the token's
`body`, `oauth_client`, and `oauth_client_id` fields directly to the credential struct,
making them accessible without having to navigate the association.
@doc """
Gets the oauth_client for a credential through its oauth_token.
For non-OAuth credentials or OAuth credentials without a token, this function
returns the credential unchanged.
## Parameters
- credential: The credential struct to transform
## Returns
- The transformed credential with OAuth fields copied from the token, or
- The original credential if it's not an OAuth credential or has no token
## Examples
# For an OAuth credential with a token
iex> with_oauth(%Credential{schema: "oauth", oauth_token: %{body: "secret", oauth_client_id: 123}})
%Credential{schema: "oauth", body: "secret", oauth_client_id: 123}
# For a non-OAuth credential
iex> with_oauth(%Credential{schema: "basic", body: "password"})
%Credential{schema: "basic", body: "password"}
"""
def oauth_client(%__MODULE__{oauth_token: %OauthToken{oauth_client: client}})
when not is_nil(client),
do: client
@spec with_oauth(t()) :: t()
def with_oauth(%__MODULE__{schema: "oauth", oauth_token: token} = credential)
when not is_nil(token) do
%{
credential
| body: token.body,
oauth_client: token.oauth_client,
oauth_client_id: token.oauth_client_id
}
end

def oauth_client(%__MODULE__{} = credential) do
credential = Lightning.Repo.preload(credential, oauth_token: :oauth_client)
oauth_client(credential)
def with_oauth(%__MODULE__{} = credential) do
credential
end

# defp validate_oauth(changeset) do
Expand Down

0 comments on commit c4cfe1b

Please sign in to comment.