### Example GitHub Authorization URL Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/endpoints.md An example of a fully constructed URL for the GitHub authorization endpoint, including client ID, redirect URI, scope, and state parameters. ```http https://github.com/login/oauth/authorize?client_id=abc123&redirect_uri=https%3A%2F%2Fexample.com%2Fauth%2Fgithub%2Fcallback&scope=user%2Cpublic_repo&state=xyz789 ``` -------------------------------- ### Phoenix Router for Ueberauth GitHub Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Example of how to configure a Phoenix router to handle authentication requests for GitHub. This setup automatically calls Ueberauth's handle_request! when a user visits the /auth/github path. ```elixir defmodule MyApp.Router do use MyApp.Web, :router scope "/auth" do pipe_through [:browser] get "/:provider", AuthController, :request end end defmodule MyApp.AuthController do def request(conn, _params) do # Ueberauth will call handle_request! via the plug render(conn, "request.html") end end ``` -------------------------------- ### Set GitHub Environment Variables Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Set the GITHUB_CLIENT_ID and GITHUB_CLIENT_SECRET environment variables before starting the application. This is an alternative to direct configuration. ```bash export GITHUB_CLIENT_ID="..." export GITHUB_CLIENT_SECRET="..." iex -S mix ``` -------------------------------- ### Set Environment Variables for GitHub Credentials Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Set the `GITHUB_CLIENT_ID` and `GITHUB_CLIENT_SECRET` environment variables before starting the application to resolve missing environment variable errors. This example shows how to export them in a shell or set them in a Dockerfile. ```bash # Before running the app export GITHUB_CLIENT_ID="..." export GITHUB_CLIENT_SECRET="..." iex -S mix ``` ```dockerfile # Dockerfile ENV GITHUB_CLIENT_ID=value ENV GITHUB_CLIENT_SECRET=value ``` -------------------------------- ### Configure Repository Management App Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Example configuration for an application that manages repositories using the GitHub provider. It sets scopes for user data, repository access, and gists. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [ default_scope: "user,repo,gist" ]} ] ``` -------------------------------- ### Configure Ueberauth GitHub Credentials Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Ensure both `client_id` and `client_secret` are configured for Ueberauth GitHub. This example shows how to set them using environment variables in `config/config.exs`. ```elixir config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: System.get_env("GITHUB_CLIENT_ID"), client_secret: System.get_env("GITHUB_CLIENT_SECRET") ``` -------------------------------- ### Handle GitHub Callback Credentials Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Example of handling the callback from GitHub authentication, extracting credentials, and storing them for later use, such as API calls. ```elixir defmodule MyApp.AuthController do def callback(conn, _params) do case conn.assigns do %{ueberauth_auth: auth} -> creds = auth.credentials user_params = %{ github_token: creds.token, github_scopes: creds.scopes, token_expires_at: creds.expires_at } MyApp.Accounts.create_or_update_user(user_params) %{ueberauth_failure: _} -> redirect(conn, to: "/") end end end ``` -------------------------------- ### Configure Multiple GitHub Apps Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Set up Ueberauth to potentially use multiple GitHub OAuth applications. This example shows how to define distinct provider configurations, though using different environment variables for credentials requires custom modifications. ```elixir # config/config.exs - base configuration config :ueberauth, Ueberauth, providers: github: {Ueberauth.Strategy.Github, [ default_scope: "user" ]}, github_staging: {Ueberauth.Strategy.Github, [ default_scope: "user" ]} # Shared OAuth config location, but strategy uses different env vars config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: {:system, "GITHUB_CLIENT_ID"}, client_secret: {:system, "GITHUB_CLIENT_SECRET"} # Note: Both strategies read from the same config location. # To use different GitHub apps, you'd need custom modifications. ``` -------------------------------- ### Configuration Error: Missing Environment Variable Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Example error message indicating that a required environment variable, specified in the configuration for Ueberauth.Strategy.Github.OAuth, is not set. ```elixir ** (RuntimeError) "GITHUB_CLIENT_ID" missing from environment, expected in config :ueberauth, Ueberauth.Strategy.Github.OAuth ``` -------------------------------- ### Example Test for GitHub Authentication Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md This Elixir test simulates a successful GitHub authentication callback. It demonstrates how to set up a connection, mock OAuth2 calls, and assert the expected assigns and user data. ```elixir defmodule MyApp.AuthTest do use ExUnit.Case test "successful GitHub authentication" do # Simulate GitHub callback with code conn = conn(:get, "/auth/github/callback", %{"code" => "test_code"}) # Mock OAuth2 calls # Assert ueberauth_auth is in assigns # Assert user data is correct end end ``` -------------------------------- ### Configuration Error: Missing Client ID Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Example error message indicating that the client_id is missing from the configuration for Ueberauth.Strategy.Github.OAuth. ```elixir ** (RuntimeError) :client_id missing from config :ueberauth, Ueberauth.Strategy.Github.OAuth ``` -------------------------------- ### Update Ueberauth Provider Configuration at Runtime Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md This example demonstrates how to dynamically update Ueberauth's provider configuration at runtime, specifically by modifying the default scope. It is generally not recommended for production environments. ```elixir # Change the default scope at runtime current_config = Application.get_env(:ueberauth, Ueberauth) updated_config = Keyword.put(current_config, :providers, [...]) Application.put_env(:ueberauth, Ueberauth, updated_config) ``` -------------------------------- ### Configure Read-Only Email Access Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Example configuration for a read-only email application using the GitHub provider. It sets the `user:email` scope. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [ default_scope: "user:email" ]} ] ``` -------------------------------- ### Authorization Header Example Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/endpoints.md API requests use the OAuth2 access token in the Authorization header. ```http Authorization: bearer ghu_16C7e42F292c6912E7... ``` -------------------------------- ### OAuth2 Client - Make Authenticated API Request Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Makes an authenticated GET request to the GitHub API. ```APIDOC ## Ueberauth.Strategy.Github.OAuth.get/4 ### Description Make an authenticated GET request to the GitHub API. ### Method N/A (Elixir function call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```elixir Ueberauth.Strategy.Github.OAuth.get(client, url, headers, options) ``` ### Response - **api_response** (map) - The response from the GitHub API. #### Success Response (200) N/A #### Response Example ```json %{body: "{\"login\": \"janedoe\"}", status: 200} ``` ``` -------------------------------- ### Ueberauth GitHub Callback Handling Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Example of how to handle the callback from GitHub in a Phoenix application. This code checks for successful authentication or failure and responds accordingly, either by processing user data or displaying an error. ```elixir defmodule MyApp.AuthController do def callback(conn, _params) do case conn.assigns do %{ueberauth_auth: auth} -> # Successfully authenticated user = auth.info IO.inspect(user) # Create or update user in your database redirect(conn, to: "/dashboard") %{ueberauth_failure: failure} -> # Authentication failed reason = inspect(failure.errors) conn |> put_flash(:error, "GitHub authentication failed: #{reason}") |> redirect(to: "/") end end end ``` -------------------------------- ### GitHub Strategy Configuration with Custom Scopes Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Configure the GitHub strategy to request specific OAuth2 scopes. This example requests user, public_repo, and notifications scopes. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [ default_scope: "user,public_repo,notifications" ]} ] ``` -------------------------------- ### Allow Per-Request Scope Override Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Illustrates how the `scope` parameter in a GET request to `/auth/github` can override the `default_scope` configured in Ueberauth. ```comment # Request: GET /auth/github?scope=user,notifications # The scope parameter overrides default_scope ``` -------------------------------- ### Ueberauth Callback Handling Logic Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Example Elixir code demonstrating how to handle Ueberauth failures in a callback function. It differentiates between transient OAuth2 errors and other permanent errors, providing appropriate user feedback or responses. ```elixir defmodule MyApp.AuthController do def callback(conn, _params) do case conn.assigns do %{ueberauth_failure: failure} -> Enum.each(failure.errors, fn {code, reason} -> Logger.error("Auth error - #{code}: #{inspect(reason)}") end) case failure.errors do [{"OAuth2", _} | _] -> # Transient error - user can retry conn |> put_flash(:error, "GitHub is temporarily unavailable. Please try again.") |> redirect(to: "/") other -> # Permanent error send_resp(conn, 500, "Authentication service error") end %{ueberauth_auth: auth} -> # Success end end end ``` -------------------------------- ### Example Ueberauth Failure Structure Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md This structure represents a Ueberauth failure during the callback phase, specifically when the user's email is not accessible as the UID. ```elixir %{ueberauth_failure: %Ueberauth.Failure{ errors: [{"error", "Unable to access the user's email address"}] }} ``` -------------------------------- ### Usage Example: Processing GitHub User Info Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/types.md This Elixir code snippet demonstrates how to extract user information from the Ueberauth.Auth.Info struct and use it to create or update a User record in the database. It handles both successful authentication and failure cases. ```elixir def callback(conn, _params) do case conn.assigns do %{ueberauth_auth: auth} -> info = auth.info user = %User{ github_login: info.nickname, name: info.name, email: info.email, bio: info.description, location: info.location, avatar_url: info.image, github_profile_url: info.urls.html_url, github_blog: info.urls.blog } Repo.insert_or_update!(user) %{ueberauth_failure: _} -> :error end end ``` -------------------------------- ### GitHub Token Exchange Success Response Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/endpoints.md Example JSON response from GitHub upon successful exchange of an authorization code for an access token. Includes the access token, token type, and granted scopes. ```json { "access_token": "ghu_16C7e42F292c6912E7...", "token_type": "bearer", "scope": "user,public_repo" } ``` -------------------------------- ### Minimal GitHub Strategy Configuration Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md This is the most basic configuration for the GitHub strategy. It requires only the strategy and an empty list of options. ```elixir github: {Ueberauth.Strategy.Github, []} ``` -------------------------------- ### Request Phase Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Initiates the authentication process by redirecting the user to GitHub's login page. ```APIDOC ## Ueberauth.Strategy.Github.handle_request!/1 ### Description Redirect to GitHub login. ### Method N/A (Elixir function call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```elixir Ueberauth.Strategy.Github.handle_request!(params) ``` ### Response N/A (Handles redirection) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Make Authenticated GET Request to GitHub API Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md This function makes an authenticated GET request to a specified GitHub API endpoint using an access token. It's used internally to fetch user data or other resources after a successful token exchange. The URL is relative to the GitHub API base URL. The function returns a tuple with either the successful response or an error reason. ```elixir alias Ueberauth.Strategy.Github.OAuth token = OAuth.get_token!([code: "..."]) # Fetch current user case OAuth.get(token, "/user") do {:ok, %OAuth2.Response{status_code: 200, body: user}} -> IO.inspect(user) # => %{"id" => 123, "login" => "johndoe", "name" => "John Doe", ...} {:ok, %OAuth2.Response{status_code: 401}} -> IO.puts("Unauthorized - token may be invalid") {:error, reason} -> IO.puts("Request failed: #{inspect(reason)}") end # Fetch user emails case OAuth.get(token, "/user/emails") do {:ok, %OAuth2.Response{status_code: 200, body: emails}} -> IO.inspect(emails) # => [%{"email" => "...", "primary" => true, "verified" => true}, ...] {:error, _} -> IO.puts("Failed to fetch emails") end ``` -------------------------------- ### Configure GitHub Client ID and Secret Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Ensure your `config.exs` includes the client_id and client_secret for the GitHub OAuth strategy. ```elixir config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: "...", client_secret: "..." ``` -------------------------------- ### Using OAuth2 Access Token in Code Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/types.md Demonstrates how to obtain an OAuth2 access token and use its fields for API requests and scope checking. ```elixir alias Ueberauth.Strategy.Github.OAuth token = OAuth.get_token!([code: "code_from_github"]) # Use the token to make API requests with OAuth2 token.access_token # => "ghu_..." token.token_type # => "bearer" # Check scopes granted scopes = token.other_params["scope"] # => "user,public_repo" ``` -------------------------------- ### handle_request!/1 Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Handles the initial redirect to the GitHub authentication page. It initiates the OAuth2 authorization request by building an authorization URL with configured scopes, state parameter, and redirect URI. Scopes can be overridden via the `scope` query parameter. ```APIDOC ## handle_request!/1 ### Description Handles the initial redirect to the GitHub authentication page. ### Method `def handle_request!(conn :: Plug.Conn.t()) :: Plug.Conn.t()` ### Parameters #### Path Parameters None #### Query Parameters - **scope** (string) - Optional - Allows overriding the default scope via the `scope` query parameter (e.g., `/auth/github?scope=user,public_repo,gist`). #### Request Body None ### Response #### Success Response (200) - **conn** (`Plug.Conn.t()`) - The connection with a redirect to GitHub's OAuth authorize endpoint. ### Request Example ```elixir # In your Phoenix router, this is automatically called when visiting /auth/github defmodule MyApp.Router do use MyApp.Web, :router scope "/auth" do pipe_through [:browser] get "/:provider", AuthController, :request end end # The AuthController delegates to Ueberauth: defmodule MyApp.AuthController do def request(conn, _params) do # Ueberauth will call handle_request! via the plug render(conn, "request.html") end end ``` ### Response Example None (redirects instead) ``` -------------------------------- ### Configure GitHub OAuth2 with Environment Variables Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Configure the client ID and secret using environment variables for enhanced security. This approach is recommended for production deployments as it avoids hardcoding sensitive credentials. ```elixir config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: {:system, "GITHUB_CLIENT_ID"}, client_secret: {:system, "GITHUB_CLIENT_SECRET"} ``` -------------------------------- ### GitHub OAuth2 Client Configuration Defaults Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Illustrates the default configuration values used when constructing an OAuth2 client for GitHub. These include the site URL, authorization and token endpoints, and default headers. ```elixir config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: "...", client_secret: "..." # Or with environment variable resolution: config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: {:system, "GITHUB_CLIENT_ID"}, client_secret: {:system, "GITHUB_CLIENT_SECRET"} ``` -------------------------------- ### get/4 Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Makes an authenticated GET request to GitHub's API. This method is used to retrieve data from GitHub endpoints after a successful token exchange. ```APIDOC ## get/4 ### Description Makes an authenticated GET request to GitHub's API. This method is used to retrieve data from GitHub endpoints after a successful token exchange. ### Method Elixir Function ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```elixir alias Ueberauth.Strategy.Github.OAuth token = OAuth.get_token!([code: "..."]) # Fetch current user case OAuth.get(token, "/user") do {:ok, %OAuth2.Response{status_code: 200, body: user}} -> IO.inspect(user) # => %{"id" => 123, "login" => "johndoe", "name" => "John Doe", ...} {:ok, %OAuth2.Response{status_code: 401}} -> IO.puts("Unauthorized - token may be invalid") {:error, reason} -> IO.puts("Request failed: #{inspect(reason)}") end # Fetch user emails case OAuth.get(token, "/user/emails") do {:ok, %OAuth2.Response{status_code: 200, body: emails}} -> IO.inspect(emails) # => [%{"email" => "...", "primary" => true, "verified" => true}, ...] {:error, _} -> IO.puts("Failed to fetch emails") end ``` ### Response #### Success Response `{:ok, OAuth2.Response.t()}` - Tuple with the HTTP status code, parsed JSON response body, and response headers. #### Response Example ```elixir # For /user endpoint: %OAuth2.Response{ status_code: 200, body: %{"id" => 123, "login" => "johndoe", "name" => "John Doe", ...}, headers: %{...} } # For /user/emails endpoint: %OAuth2.Response{ status_code: 200, body: [%{"email" => "...", "primary" => true, "verified" => true}, ...], headers: %{...} } ``` ### Throws `{:error, term()}` - If the request fails. ``` -------------------------------- ### OAuth2 Client - Construct Client Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Constructs an OAuth2 client for interacting with the GitHub API. ```APIDOC ## Ueberauth.Strategy.Github.OAuth.client/1 ### Description Construct an OAuth2 client for interacting with the GitHub API. ### Method N/A (Elixir function call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```elixir Ueberauth.Strategy.Github.OAuth.client(github_credentials) ``` ### Response - **client** (object) - The configured OAuth2 client. #### Success Response (200) N/A #### Response Example ```json %{client_id: "...", client_secret: "...", token_url: "..."} ``` ``` -------------------------------- ### GitHub Token Exchange Error Response Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/endpoints.md Example JSON response from GitHub indicating an error during the token exchange process, such as an invalid or expired authorization code. ```json { "error": "bad_verification_code", "error_description": "The code passed is incorrect or expired.", "error_uri": "https://docs.github.com/..." } ``` -------------------------------- ### Extract GitHub User Profile Info Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Use this function to get structured user profile data like name, email, and avatar. It handles private email synthesis if configured. ```elixir def info(conn :: Plug.Conn.t()) :: Ueberauth.Auth.Info.t() ``` ```elixir defmodule MyApp.AuthController do def callback(conn, _params) do case conn.assigns do %{ueberauth_auth: auth} -> info = auth.info user = %{ name: info.name, email: info.email, nickname: info.nickname, avatar_url: info.image, bio: info.description, location: info.location, github_profile: info.urls.html_url } MyApp.Accounts.create_or_update_user(user) %{ueberauth_failure: _} -> :error end end end ``` -------------------------------- ### Test OAuth Client Configuration Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Verify that the OAuth client correctly identifies configuration errors when credentials are not provided. This test assumes an `authenticate_with_github/0` function exists. ```elixir defmodule MyApp.AuthTest do import ExUnit.Assertions test "OAuth client fails without client_id" do # This would raise at startup, so verify in integration tests: assert {:error, :config_error} = authenticate_with_github() end end ``` -------------------------------- ### Define Auth Routes Source: https://github.com/ueberauth/ueberauth_github/blob/master/README.md Define the request and callback routes for authentication in your router. ```elixir scope "/auth", MyApp do pipe_through :browser get "/:provider", AuthController, :request get "/:provider/callback", AuthController, :callback end ``` -------------------------------- ### Configure Limited Scope for Read-Only GitHub Access Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Configure Ueberauth with a limited scope for read-only access to GitHub. This setup is suitable for applications that only need to read public profile information and emails. ```elixir config :ueberauth, Ueberauth, providers: github: {Ueberauth.Strategy.Github, [ default_scope: "user:email" # Read-only email + public info ]} ``` -------------------------------- ### Define Authentication Routes Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Define routes for initiating authentication requests and handling callbacks within your application's router. ```elixir scope "/auth" do pipe_through :browser get "/:provider", AuthController, :request get "/:provider/callback", AuthController, :callback end ``` -------------------------------- ### Enable Debug Logging for Ueberauth Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Configure Ueberauth to output detailed debug information in your development environment. This is typically done in the `config/dev.exs` file. ```elixir config :logger, level: :debug config :oauth2, debug: true ``` -------------------------------- ### Create GitHub OAuth2 Client Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Constructs an OAuth2 client pre-configured for GitHub's API. This client can be used for direct API requests. It merges provided options with default GitHub-specific settings. ```elixir alias Ueberauth.Strategy.Github.OAuth client = OAuth.client() client = OAuth.client(redirect_uri: "http://localhost:4000/auth/github/callback") ``` -------------------------------- ### Development Configuration for Ueberauth GitHub Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Configure Ueberauth for GitHub in a development environment. Uses environment variables with fallback default values for client ID and secret. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [ default_scope: "user,public_repo" ]} ] config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: System.get_env("GITHUB_CLIENT_ID", "dev-client-id"), client_secret: System.get_env("GITHUB_CLIENT_SECRET", "dev-secret") ``` -------------------------------- ### Handling OAuth2 Message Errors in Ueberauth Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Examples of Ueberauth failure structures when the GitHub API returns an error with a 'message' field, such as 'Bad credentials' or rate limit messages. This helps in identifying specific API-level issues. ```elixir %{ueberauth_failure: %Ueberauth.Failure{ errors: [{"OAuth2", "API rate limit exceeded. (But here's the good news: Authenticated requests get a higher rate limit. Check out the documentation for more details.)"}] }} ``` ```elixir %{ueberauth_failure: %Ueberauth.Failure{ errors: [{"OAuth2", "Bad credentials"}] }} ``` -------------------------------- ### Monitor Logs in a File Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Tail a log file to continuously monitor application logs. This is helpful when running the application in the background or for historical analysis. ```bash tail -f logs/dev.log ``` -------------------------------- ### Handling OAuth2 Request Errors in Ueberauth Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Examples of Ueberauth failure structures for various OAuth2 request errors like network issues, rate limiting, and server errors. Use this to inspect and react to different failure reasons. ```elixir %{ueberauth_failure: %Ueberauth.Failure{ errors: [{"OAuth2", {:econnrefused, "Connection refused"}}] }} ``` ```elixir %{ueberauth_failure: %Ueberauth.Failure{ errors: [{"OAuth2", "API rate limit exceeded"}] }} ``` ```elixir %{ueberauth_failure: %Ueberauth.Failure{ errors: [{"OAuth2", "Internal Server Error"}] }} ``` ```elixir %{ueberauth_failure: %Ueberauth.Failure{ errors: [{"OAuth2", "unknown error"}] }} ``` -------------------------------- ### client/1 Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Constructs an OAuth2 client for making requests to GitHub. This client is pre-configured with GitHub-specific defaults for site, authorize_url, token_url, and headers. It requires client_id and client_secret to be configured in the application's Ueberauth settings. ```APIDOC ## client/1 ### Description Constructs an OAuth2 client for making requests to GitHub. ### Method Elixir Function ### Signature `def client(opts :: keyword()) :: OAuth2.Client.t()` ### Parameters #### Keyword Parameters - **opts** (keyword()) - Optional - Default: `[]` - Additional OAuth2 options to merge with defaults. ### Return Type `OAuth2.Client.t()` - An OAuth2 client struct configured for GitHub. ### Description Creates an OAuth2 client with GitHub-specific defaults. Requires `client_id` and `client_secret` to be configured in the application configuration under `:ueberauth` > `Ueberauth.Strategy.Github.OAuth`. Supports reading credentials from environment variables via `{:system, "ENV_VAR_NAME"}` syntax. **Configuration Requirements:** The application must have this configuration: ```elixir config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: "...", client_secret: "..." ``` Or with environment variable resolution: ```elixir config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: {:system, "GITHUB_CLIENT_ID"}, client_secret: {:system, "GITHUB_CLIENT_SECRET"} ``` **Defaults:** - `site`: "https://api.github.com" - `authorize_url`: "https://github.com/login/oauth/authorize" - `token_url`: "https://github.com/login/oauth/access_token" - `headers`: `[{"user-agent", "ueberauth-github"}]` **Throws:** - `RuntimeError` - If `client_id` or `client_secret` is missing from config - `RuntimeError` - If environment variable specified for credential is not set ### Usage Example: ```elixir alias Ueberauth.Strategy.Github.OAuth client = OAuth.client() # => OAuth2.Client with GitHub configuration # With custom options client = OAuth.client(redirect_uri: "http://localhost:4000/auth/github/callback") ``` ``` -------------------------------- ### Configure Ueberauth for GitHub Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Sets up the Ueberauth configuration to use the GitHub strategy. It also configures the OAuth client ID and secret for the GitHub OAuth strategy, supporting environment variable resolution. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, []} ] config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: System.get_env("GITHUB_CLIENT_ID"), client_secret: System.get_env("GITHUB_CLIENT_SECRET") ``` -------------------------------- ### Complete Ueberauth GitHub Configuration Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md A comprehensive configuration for Ueberauth's GitHub provider, suitable for production environments. It includes provider-specific options and environment variable-based client credentials. ```elixir config :ueberauth, Ueberauth, providers: github: {Ueberauth.Strategy.Github, [ uid_field: :id, default_scope: "user,public_repo", send_redirect_uri: true, allow_private_emails: false ]} config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: {:system, "GITHUB_CLIENT_ID"}, client_secret: {:system, "GITHUB_CLIENT_SECRET"} # config/prod.exs (override for production if needed) config :ueberauth, Ueberauth, providers: github: {Ueberauth.Strategy.Github, [ default_scope: "user,public_repo", send_redirect_uri: false # Behind SSL-terminating proxy ]} ``` -------------------------------- ### Configure Ueberauth with Github Provider Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Configure Ueberauth to use the Github strategy and set default scopes. Client ID and secret are read from system environment variables. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [ default_scope: "user,public_repo" ]} ] config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: {:system, "GITHUB_CLIENT_ID"}, client_secret: {:system, "GITHUB_CLIENT_SECRET"} ``` -------------------------------- ### Accessing GitHub Raw Data in Ueberauth Callback Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/types.md Demonstrates how to access and utilize raw token and user data from the Ueberauth.Auth.Extra struct within a Ueberauth callback function to create or update a user record. ```elixir def callback(conn, _params) do case conn.assigns do %{ueberauth_auth: auth} -> extra = auth.extra # Access raw token token = extra.raw_info.token token_value = token.access_token # Access raw user data user = extra.raw_info.user github_id = user["id"] created_at = user["created_at"] # Access emails if available emails = user["emails"] || [] primary_email = Enum.find(emails, & &1["primary"]) Repo.insert!(%User{ github_id: github_id, github_token: token_value, created_at: created_at, primary_email: primary_email["email"] }) %{ueberauth_failure: _} -> :error end end ``` -------------------------------- ### Configure GitHub OAuth Credentials Source: https://github.com/ueberauth/ueberauth_github/blob/master/README.md Set your GitHub OAuth client ID and client secret. These can be read from environment variables or directly configured. ```elixir config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: System.get_env("GITHUB_CLIENT_ID"), client_secret: System.get_env("GITHUB_CLIENT_SECRET") ``` ```elixir config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: {:system, "GITHUB_CLIENT_ID"}, client_secret: {:system, "GITHUB_CLIENT_SECRET"} ``` -------------------------------- ### Graceful Handling of Email Fetching Failures Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Illustrates how the Ueberauth GitHub strategy gracefully handles non-2xx responses from the '/user/emails' endpoint. If email fetching fails, the strategy continues with the user data obtained from the '/user' endpoint. ```elixir # If /user/emails fails, the strategy continues with just the /user data case Ueberauth.Strategy.Github.OAuth.get(token, "/user/emails") do {:ok, %OAuth2.Response{status_code: status_code, body: emails}} when status_code in 200..399 -> user = Map.put(user, "emails", emails) put_private(conn, :github_user, user) # Continue on as before - don't set an error {:error, _} -> put_private(conn, :github_user, user) end ``` -------------------------------- ### GitHub Strategy Configuration with Email as UID and Private Email Support Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md This configuration uses the user's email as the unique identifier and enables support for private email addresses. This is useful if GitHub's primary email is private. ```elixir github: {Ueberauth.Strategy.Github, [ uid_field: :email, allow_private_emails: true ]} ``` -------------------------------- ### Register GitHub Strategy with Ueberauth Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Register the GitHub strategy with Ueberauth by adding it to the provider configuration. This is the initial step for integrating GitHub authentication. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [ # Strategy options go here ]} ] ``` -------------------------------- ### Production Configuration for Ueberauth GitHub Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Configure Ueberauth for GitHub in a production environment. Uses system environment variables for client ID and secret, and disables redirect URI sending when behind a proxy. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [ default_scope: "user,public_repo", send_redirect_uri: false # Behind proxy ]} ] config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: {:system, "GITHUB_CLIENT_ID"}, client_secret: {:system, "GITHUB_CLIENT_SECRET"} ``` -------------------------------- ### Override Scopes via Request Parameter Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Demonstrates how to override the default scopes by including a `scope` query parameter in the authorization request URL. ```http GET /auth/github?scope=user,repo,notifications ``` -------------------------------- ### Add ueberauth_github to Mix Dependencies Source: https://github.com/ueberauth/ueberauth_github/blob/master/README.md Add the ueberauth_github package to your project's dependencies in mix.exs. ```elixir def deps do [ {:ueberauth_github, "~> 0.8"} ] end ``` -------------------------------- ### Default Headers Configuration Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/endpoints.md Defines default headers, including User-Agent, for Ueberauth GitHub. ```elixir @defaults [ headers: [{"user-agent", "ueberauth-github"}] ] ``` -------------------------------- ### Static Configuration of GitHub OAuth2 Credentials Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md An alternative method to hardcode credentials directly in the configuration. This is not recommended for production environments due to security risks. ```elixir config :ueberauth, Ueberauth.Strategy.Github.OAuth, client_id: "abc123def456...", client_secret: "xyz789..." ``` -------------------------------- ### Handling Ueberauth Failure Struct Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Inspect connection assigns to check for an `ueberauth_failure` key. The failure struct contains a list of error tuples. ```elixir case conn.assigns do %{ueberauth_failure: failure} -> # failure is an Ueberauth.Failure struct failure.errors # List of error tuples %{ueberauth_auth: auth} -> # Successful authentication end ``` -------------------------------- ### Configure GitHub Provider in Überauth Source: https://github.com/ueberauth/ueberauth_github/blob/master/README.md Configure the GitHub strategy within your Überauth configuration in config/config.exs. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, []} ] ``` -------------------------------- ### Ueberauth GitHub Cleanup Usage Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Illustrates that handle_cleanup! is automatically invoked by Ueberauth post-callback and requires no explicit implementation in application code. ```elixir # Automatically called by Ueberauth after the callback phase # No explicit usage required in application code ``` -------------------------------- ### Handle Github Authentication Callback Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Implement the callback action in your AuthController to process successful or failed authentication attempts from Github. Extracts user info and token on success. ```elixir defmodule MyApp.AuthController do def callback(conn, _params) do case conn.assigns do %{ueberauth_auth: auth} -> # Successful authentication user_info = auth.info token = auth.credentials.token # Create/update user and session redirect(conn, to: "/dashboard") %{ueberauth_failure: failure} -> # Authentication failed redirect(conn, to: "/") end end end ``` -------------------------------- ### Enable Debug Logging for Authentication Flow Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Enable debug logging for both Ueberauth and the underlying OAuth2 library. Check application logs for detailed information about OAuth2 requests and responses. ```elixir # config/dev.exs config :logger, level: :debug config :oauth2, debug: true ``` -------------------------------- ### Enable Private Email Scope Source: https://github.com/ueberauth/ueberauth_github/blob/master/README.md Configure the GitHub strategy to request private email addresses, which will be formatted as id+username@users.noreply.github.com. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [allow_private_emails: true]} ] ``` -------------------------------- ### GitHub Strategy Configuration for SSL-Terminating Proxies Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/configuration.md Configure the GitHub strategy to disable sending the `redirect_uri` parameter. This is useful for applications behind a proxy that handles SSL termination to prevent URI mismatch errors. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [ send_redirect_uri: false ]} ] ``` -------------------------------- ### Configure Default Scope for GitHub Strategy Source: https://github.com/ueberauth/ueberauth_github/blob/master/README.md Set a default scope for the GitHub strategy if not provided in the request. ```elixir config :ueberauth, Ueberauth, providers: [ github: {Ueberauth.Strategy.Github, [default_scope: "user,public_repo"]} ] ``` -------------------------------- ### handle_callback!/1 Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Processes the OAuth2 callback from GitHub after user authorization. It handles the exchange of the authorization code for an access token and fetches user information, or stores any errors encountered during the process. ```APIDOC ## handle_callback!/1 ### Description Processes the OAuth2 callback from GitHub after user authorization. ### Method `def handle_callback!(conn :: Plug.Conn.t()) :: Plug.Conn.t()` ### Parameters #### Path Parameters None #### Query Parameters - **code** (string) - Required - The authorization code received from GitHub. - **error** (string) - Optional - An error code returned by GitHub if authorization failed. #### Request Body None ### Response #### Success Response (200) - **conn** (`Plug.Conn.t()`) - The connection with authentication results attached in `conn.assigns`. ### Request Example ```elixir defmodule MyApp.AuthController do def callback(conn, _params) do case conn.assigns do %{ueberauth_auth: auth} -> # Successfully authenticated user = auth.info IO.inspect(user) # Create or update user in your database redirect(conn, to: "/dashboard") %{ueberauth_failure: failure} -> # Authentication failed reason = inspect(failure.errors) conn |> put_flash(:error, "GitHub authentication failed: #{reason}") |> redirect(to: "/") end end end ``` ### Response Example None (results are stored in `conn.assigns`) ``` -------------------------------- ### Ueberauth Github handle_request! signature Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/api-reference.md Defines the function signature for handling the initial redirect to the GitHub authentication page. It takes a Plug connection and returns a modified connection. ```elixir def handle_request!(conn :: Plug.Conn.t()) :: Plug.Conn.t() ``` -------------------------------- ### Callback Phase - Cleanup Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Cleans up any temporary data associated with the authentication callback. ```APIDOC ## Ueberauth.Strategy.Github.handle_cleanup!/1 ### Description Clean up temporary data after the authentication callback. ### Method N/A (Elixir function call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```elixir Ueberauth.Strategy.Github.handle_cleanup!(state) ``` ### Response N/A (Performs cleanup) #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### OAuth2 Client - Build Authorization URL Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md Builds the authorization URL required to initiate the OAuth2 flow. ```APIDOC ## Ueberauth.Strategy.Github.OAuth.authorize_url!/2 ### Description Build the authorization URL for the OAuth2 flow. ### Method N/A (Elixir function call) ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```elixir Ueberauth.Strategy.Github.OAuth.authorize_url!(client, options) ``` ### Response - **url** (string) - The complete authorization URL. #### Success Response (200) N/A #### Response Example ```json "https://github.com/login/oauth/authorize?client_id=...&redirect_uri=..." ``` ``` -------------------------------- ### Monitor Logs in IEx Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/errors.md Run your Elixir application within an IEx session to view logs directly in the console. This is useful for real-time debugging. ```bash iex -S mix ``` -------------------------------- ### Handle Authentication Errors Source: https://github.com/ueberauth/ueberauth_github/blob/master/_autodocs/README.md This snippet shows how to process authentication errors returned in the `ueberauth_failure` struct. It iterates through the errors and logs them. ```elixir %{ueberauth_failure: failure} -> Enum.each(failure.errors, fn {code, reason} -> Logger.warn("Auth error - #{code}: #{reason}") end) ```