Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update/intialize the access token with elixir starter kit #12

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Hammadkhan0034
Copy link

Explain your changes

This Pull request introduces a more structured approach to handling authentication tokens within the application by adding three new functions: init_with_tokens/3, get_kinde_client/1, and authenticated_request/4. These changes improve how access and refresh tokens are managed within the connection (conn).

  1. init_with_tokens/3 stores the access_token and refresh_token in the conn.
  2. get_kinde_client/1 retrieves the token map from the conn.
  3. authenticated_request/4 utilizes the access_token from the map to set up the necessary headers for making an authenticated HTTP request.

Copy link
Contributor

coderabbitai bot commented Aug 20, 2024

Walkthrough

The changes to the KindeClientSDK module introduce new functionalities for managing authentication tokens. The init_with_tokens/3 function initializes the client with access and refresh tokens, while get_kinde_client/1 retrieves the Kinde client from the connection. The authenticated_request/1 function has been modified to check for the presence of the access token before making an authenticated API request. These updates enhance the SDK's capabilities in handling authentication.

Changes

Files Change Summary
lib/kinde_sdk/kinde_client_sdk.ex Added init_with_tokens/3 for initializing tokens, introduced get_kinde_client/1 for retrieving the Kinde client, and modified authenticated_request/1 to utilize the access token for API requests.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant KindeClientSDK
    participant API

    Client->>KindeClientSDK: init_with_tokens(conn, access_token, refresh_token)
    KindeClientSDK-->>Client: Store tokens in assigns

    Client->>KindeClientSDK: authenticated_request(conn)
    KindeClientSDK->>KindeClientSDK: get_kinde_client(conn)
    KindeClientSDK-->>Client: Retrieve access token
    KindeClientSDK->>API: Make request with Bearer token
    API-->>KindeClientSDK: Response
    KindeClientSDK-->>Client: Return response
Loading

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 35e9ec1 and 020f900.

Files selected for processing (1)
  • lib/kinde_sdk/kinde_client_sdk.ex (1 hunks)
Additional comments not posted (1)
lib/kinde_sdk/kinde_client_sdk.ex (1)

1013-1015: LGTM!

The get_kinde_client/1 function efficiently retrieves the client from the connection's assigns.

lib/kinde_sdk/kinde_client_sdk.ex Outdated Show resolved Hide resolved
lib/kinde_sdk/kinde_client_sdk.ex Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between 020f900 and d26b8e5.

Files selected for processing (1)
  • lib/kinde_sdk/kinde_client_sdk.ex (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • lib/kinde_sdk/kinde_client_sdk.ex

@mhtouseef9
Copy link

approved

@onderay onderay mentioned this pull request Aug 29, 2024
3 tasks
lib/kinde_sdk/kinde_client_sdk.ex Outdated Show resolved Hide resolved
end


def authenticated_request(conn, method, url, params \\ %{}) do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what this method is supposed to do?
It takes a method, url and params but doesn't do anything with it, and just returns headers?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its been resolved and pushed.

@tcoopman
Copy link

To be honest, I'm not sure how this PR has to be used.
I've tried it out but I'm kinda stuck.

In the light of #11, let's say I have the access and refresh tokens.

        conn =
          KindeClientSDK.init_with_tokens(
            conn,
            get_session(conn, :kinde_access_token),
            get_session(conn, :kinde_refresh_token)
          )

        dbg(KindeClientSDK.authenticated?(conn))

returns false??

How do I get that to return true? Or can you show me some code how to use init_with_tokens

@tcoopman
Copy link

Just to be clear, if the cache is still alive, I think I can get it working. But what if the cache is not available anymore?

@DanielRivers
Copy link
Contributor

Thanks for your commends @tcoopman, are you able to address these please @Hammadkhan0034 ?

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between d26b8e5 and c0cb0e4.

Files selected for processing (1)
  • lib/kinde_sdk/kinde_client_sdk.ex (1 hunks)
Additional comments not posted (3)
lib/kinde_sdk/kinde_client_sdk.ex (3)

1001-1022: Review of init_with_tokens/3: Enhanced token initialization.

The function init_with_tokens correctly initializes the connection with access and refresh tokens. The error handling for nil tokens is implemented as suggested in previous comments, ensuring robustness. The documentation is clear and provides all necessary details about the function's purpose and usage.

The changes are approved as they meet the requirements for functionality and documentation.


1024-1026: Review of get_kinde_client/1: Efficient token retrieval.

The function get_kinde_client retrieves the token map from the connection efficiently. The implementation is straightforward and uses the Elixir's assigns map correctly to fetch the stored client.

The changes are approved as they correctly implement the token retrieval functionality.


1028-1037: Review of authenticated_request/4: Proper use of access tokens in requests.

The function authenticated_request has been updated to utilize the get_kinde_client function for retrieving the client and its access token. The error handling for missing client or access token is appropriate, preventing potential runtime errors. The construction of the authorization header using the access token is correctly implemented.

The changes are approved as they enhance the security and functionality of making authenticated HTTP requests.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

Commits

Files that changed from the base of the PR and between c0cb0e4 and 08c569e.

Files selected for processing (1)
  • lib/kinde_sdk/kinde_client_sdk.ex (1 hunks)
Files skipped from review as they are similar to previous changes (1)
  • lib/kinde_sdk/kinde_client_sdk.ex

@Hammadkhan0034
Copy link
Author

Yes if the valid refresh token is available in cache, you can use it to obtain new token, if both cache and refresh token are unavailable or expires then user will need re-authentication.

@onderay onderay requested a review from mhtouseef9 September 20, 2024 06:58
@DanielRivers
Copy link
Contributor

@coderabbitai review

Copy link
Contributor

coderabbitai bot commented Sep 25, 2024

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Outside diff range and nitpick comments (1)
lib/kinde_sdk/kinde_client_sdk.ex (1)

1001-1040: Enhance overall consistency and completeness of new functions.

The new functions (init_with_tokens/3, get_kinde_client/1, and authenticated_request/1) add valuable token management and authentication capabilities to the SDK. However, there are some inconsistencies in documentation and error handling that should be addressed:

  1. init_with_tokens/3 has detailed documentation, while the other functions lack it.
  2. Error handling approaches differ between functions.
  3. The authenticated_request/1 function is incomplete compared to its intended functionality.

To improve the overall quality and consistency of the SDK:

  1. Ensure all public functions have clear and consistent documentation.
  2. Standardize error handling approaches across functions.
  3. Complete the implementation of authenticated_request/1 as suggested in the previous comment.
  4. Consider adding unit tests for these new functions to ensure they work as expected and to prevent regressions in future updates.

By addressing these points, you'll significantly improve the usability and reliability of the SDK for developers integrating with Kinde.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 08c569e and c45e730.

📒 Files selected for processing (1)
  • lib/kinde_sdk/kinde_client_sdk.ex (1 hunks)

Comment on lines +1026 to +1028
def get_kinde_client(conn) do
conn.assigns[:kinde_client]
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add documentation and error handling to get_kinde_client/1.

The function lacks documentation and error handling, which could be improved for better usability and robustness.

Consider updating the function as follows:

@doc """
Retrieves the Kinde client from the connection's assigns.

## Parameters
- `conn`: The connection containing the Kinde client.

## Returns
- The Kinde client if found, or nil if not present.

## Examples
    client = get_kinde_client(conn)
"""
def get_kinde_client(conn) do
  conn.assigns[:kinde_client]
end

This change adds clear documentation for the function. Note that the function returns nil if the client is not found in the assigns, which is the default behavior of accessing a map with []. If you want to handle this case differently, you could add explicit error handling:

def get_kinde_client(conn) do
  case conn.assigns[:kinde_client] do
    nil -> raise "Kinde client not found in connection"
    client -> client
  end
end

Choose the approach that best fits your error handling strategy.

Comment on lines +1030 to +1039
def authenticated_request(conn) do
client = get_kinde_client(conn)

if is_nil(client) or is_nil(client.access_token) do
raise "Kinde Client or access token is missing"
end

access_token = client.access_token
headers = [{"Authorization", "Bearer #{access_token}"}]
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incomplete implementation of authenticated_request/1.

The current implementation of authenticated_request/1 has several issues:

  1. It lacks documentation.
  2. It doesn't use the method, url, and params parameters mentioned in a previous comment.
  3. It creates an authorization header but doesn't actually make a request.

To address these issues, consider the following improvements:

  1. Add documentation to explain the function's purpose and parameters.
  2. Implement the actual request using the method, url, and params.
  3. Return the response from the authenticated request.

Here's a suggested implementation:

@doc """
Makes an authenticated request using the Kinde client's access token.

## Parameters
- `conn`: The connection containing the Kinde client.
- `method`: The HTTP method for the request (e.g., :get, :post).
- `url`: The URL for the request.
- `params`: Optional parameters for the request (default: %{}).

## Returns
- The response from the authenticated request.

## Raises
- RuntimeError if the Kinde client or access token is missing.
"""
def authenticated_request(conn, method, url, params \\ %{}) do
  client = get_kinde_client(conn)

  if is_nil(client) or is_nil(client.access_token) do
    raise "Kinde Client or access token is missing"
  end

  headers = [{"Authorization", "Bearer #{client.access_token}"}]
  
  # Make the actual request using a HTTP client library (e.g., HTTPoison)
  case HTTPoison.request(method, url, Jason.encode!(params), headers) do
    {:ok, response} -> response
    {:error, error} -> raise "Request failed: #{inspect(error)}"
  end
end

This implementation completes the function by making the actual authenticated request and handling the response.

Comment on lines +1001 to +1024

@doc """
Initializes the connection with access and refresh tokens.

## Parameters
- `conn`: The connection to assign the tokens to.
- `access_token`: The access token to be stored.
- `refresh_token`: The refresh token to be stored.

## Returns
- The updated connection with assigned tokens.
"""
def init_with_tokens(conn, access_token, refresh_token) do
if is_nil(access_token) or is_nil(refresh_token) do
raise ArgumentError, "Tokens cannot be nil"
end

client = %{
access_token: access_token,
refresh_token: refresh_token
}

Conn.assign(conn, :kinde_client, client)
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider additional validation for empty string tokens.

The function correctly checks for nil tokens, but it might be beneficial to also check for empty strings. This would prevent potential issues with empty tokens being treated as valid.

Consider updating the validation as follows:

-    if is_nil(access_token) or is_nil(refresh_token) do
-      raise ArgumentError, "Tokens cannot be nil"
+    if is_nil(access_token) or access_token == "" or is_nil(refresh_token) or refresh_token == "" do
+      raise ArgumentError, "Tokens cannot be nil or empty"
     end

This change ensures that both nil and empty string tokens are caught, improving the robustness of the function.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@doc """
Initializes the connection with access and refresh tokens.
## Parameters
- `conn`: The connection to assign the tokens to.
- `access_token`: The access token to be stored.
- `refresh_token`: The refresh token to be stored.
## Returns
- The updated connection with assigned tokens.
"""
def init_with_tokens(conn, access_token, refresh_token) do
if is_nil(access_token) or is_nil(refresh_token) do
raise ArgumentError, "Tokens cannot be nil"
end
client = %{
access_token: access_token,
refresh_token: refresh_token
}
Conn.assign(conn, :kinde_client, client)
end
@doc """
Initializes the connection with access and refresh tokens.
## Parameters
- `conn`: The connection to assign the tokens to.
- `access_token`: The access token to be stored.
- `refresh_token`: The refresh token to be stored.
## Returns
- The updated connection with assigned tokens.
"""
def init_with_tokens(conn, access_token, refresh_token) do
if is_nil(access_token) or access_token == "" or is_nil(refresh_token) or refresh_token == "" do
raise ArgumentError, "Tokens cannot be nil or empty"
end
client = %{
access_token: access_token,
refresh_token: refresh_token
}
Conn.assign(conn, :kinde_client, client)
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants