Packages

phoenix_kit

1.6.4
1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib phoenix_kit users oauth_config.ex
Raw

lib/phoenix_kit/users/oauth_config.ex

defmodule PhoenixKit.Users.OAuthConfig do
@moduledoc """
Runtime OAuth configuration management using database credentials.
This module provides functions to configure OAuth providers at runtime
by reading credentials from the database and updating the application
configuration dynamically.
"""
alias PhoenixKit.Settings
require Logger
@doc """
Configures all OAuth providers from database settings.
This function reads OAuth credentials from the database and updates
the application configuration at runtime. It should be called:
- On application startup
- After updating OAuth credentials via admin UI
Skips configuration if OAuth is disabled in settings (oauth_enabled = false).
## Examples
iex> PhoenixKit.Users.OAuthConfig.configure_providers()
:ok
"""
def configure_providers do
# Always configure Ueberauth base with available providers
# This ensures Ueberauth has providers configured even if oauth_enabled is false
# The oauth_enabled flag controls UI visibility, not the underlying OAuth infrastructure
configure_ueberauth_base()
configure_google()
configure_apple()
configure_github()
configure_facebook()
:ok
end
@doc """
Configures a specific OAuth provider from database settings.
## Examples
iex> PhoenixKit.Users.OAuthConfig.configure_provider(:google)
:ok
"""
def configure_provider(provider) when provider in [:google, :apple, :github, :facebook] do
case provider do
:google -> configure_google()
:apple -> configure_apple()
:github -> configure_github()
:facebook -> configure_facebook()
end
end
# Configure base Ueberauth with available providers
defp configure_ueberauth_base do
providers = build_provider_list()
# FIXED: Preserve existing base_path or set default based on PhoenixKit URL prefix
# Get current config to preserve any existing settings
current_config = Application.get_env(:ueberauth, Ueberauth, [])
# Preserve base_path if it exists, or set default based on PhoenixKit URL prefix
base_path = Keyword.get(current_config, :base_path) || get_oauth_base_path()
config = [
base_path: base_path,
providers: providers
]
# Always update Ueberauth configuration, even if providers list is empty
# This ensures Ueberauth has a valid configuration at all times
Application.put_env(:ueberauth, Ueberauth, config)
if providers != %{} do
Logger.info(
"OAuth: Configured Ueberauth with providers: #{inspect(Map.keys(providers))} at base_path: #{base_path}"
)
else
Logger.info(
"OAuth: Configured Ueberauth with no active providers at base_path: #{base_path}"
)
end
end
# Helper to get OAuth base path from PhoenixKit URL prefix
defp get_oauth_base_path do
url_prefix = PhoenixKit.Config.get_url_prefix()
case url_prefix do
"" -> "/users/auth"
prefix -> "#{prefix}/users/auth"
end
end
# Build the list of available providers based on configured credentials
defp build_provider_list do
providers = %{}
# Add Google if credentials exist
providers =
if Settings.has_oauth_credentials?(:google) and
Settings.get_boolean_setting("oauth_google_enabled", false) do
Map.put(providers, :google, {Ueberauth.Strategy.Google, []})
else
providers
end
# Add Apple if credentials exist
providers =
if Settings.has_oauth_credentials?(:apple) and
Settings.get_boolean_setting("oauth_apple_enabled", false) do
Map.put(providers, :apple, {Ueberauth.Strategy.Apple, []})
else
providers
end
# Add GitHub if credentials exist
providers =
if Settings.has_oauth_credentials?(:github) and
Settings.get_boolean_setting("oauth_github_enabled", false) do
Map.put(providers, :github, {Ueberauth.Strategy.Github, []})
else
providers
end
# Add Facebook if credentials exist
providers =
if Settings.has_oauth_credentials?(:facebook) and
Settings.get_boolean_setting("oauth_facebook_enabled", false) do
Map.put(providers, :facebook, {Ueberauth.Strategy.Facebook, []})
else
providers
end
providers
end
# Configure Google OAuth
defp configure_google do
if Settings.get_boolean_setting("oauth_google_enabled", false) do
credentials = Settings.get_oauth_credentials(:google)
if credentials.client_id != "" and credentials.client_secret != "" do
config = [
client_id: credentials.client_id,
client_secret: credentials.client_secret
]
Application.put_env(:ueberauth, Ueberauth.Strategy.Google.OAuth, config)
Logger.info("OAuth: Configured Google OAuth provider")
else
Logger.warning("OAuth: Google enabled but credentials not configured")
end
end
end
# Configure Apple OAuth
defp configure_apple do
if Settings.get_boolean_setting("oauth_apple_enabled", false) do
credentials = Settings.get_oauth_credentials(:apple)
if credentials.client_id != "" and
credentials.team_id != "" and
credentials.key_id != "" and
credentials.private_key != "" do
config = [
client_id: credentials.client_id,
team_id: credentials.team_id,
key_id: credentials.key_id,
private_key: credentials.private_key
]
Application.put_env(:ueberauth, Ueberauth.Strategy.Apple.OAuth, config)
Logger.info("OAuth: Configured Apple OAuth provider")
else
Logger.warning("OAuth: Apple enabled but credentials not fully configured")
end
end
end
# Configure GitHub OAuth
defp configure_github do
if Settings.get_boolean_setting("oauth_github_enabled", false) do
credentials = Settings.get_oauth_credentials(:github)
if credentials.client_id != "" and credentials.client_secret != "" do
config = [
client_id: credentials.client_id,
client_secret: credentials.client_secret
]
Application.put_env(:ueberauth, Ueberauth.Strategy.Github.OAuth, config)
Logger.info("OAuth: Configured GitHub OAuth provider")
else
Logger.warning("OAuth: GitHub enabled but credentials not configured")
end
end
end
# Configure Facebook OAuth
defp configure_facebook do
if Settings.get_boolean_setting("oauth_facebook_enabled", false) do
credentials = Settings.get_oauth_credentials(:facebook)
if credentials.app_id != "" and credentials.app_secret != "" do
config = [
client_id: credentials.app_id,
client_secret: credentials.app_secret
]
Application.put_env(:ueberauth, Ueberauth.Strategy.Facebook.OAuth, config)
Logger.info("OAuth: Configured Facebook OAuth provider")
else
Logger.warning("OAuth: Facebook enabled but credentials not configured")
end
end
end
@doc """
Validates OAuth credentials for a specific provider.
Returns `{:ok, provider}` if credentials are valid, or `{:error, reason}` if not.
## Examples
iex> PhoenixKit.Users.OAuthConfig.validate_credentials(:google)
{:ok, :google}
iex> PhoenixKit.Users.OAuthConfig.validate_credentials(:apple)
{:error, "Missing Apple private key"}
"""
def validate_credentials(provider) when provider in [:google, :apple, :github, :facebook] do
credentials = Settings.get_oauth_credentials(provider)
case provider do
:google -> validate_google_credentials(credentials)
:apple -> validate_apple_credentials(credentials)
:github -> validate_github_credentials(credentials)
:facebook -> validate_facebook_credentials(credentials)
end
end
defp validate_google_credentials(credentials) do
missing = find_missing_google_credentials(credentials)
if missing == [] do
{:ok, :google}
else
{:error, "Missing Google OAuth credentials: #{Enum.join(missing, ", ")}"}
end
end
defp validate_apple_credentials(credentials) do
missing = find_missing_apple_credentials(credentials)
if missing == [] do
{:ok, :apple}
else
{:error, "Missing Apple OAuth credentials: #{Enum.join(missing, ", ")}"}
end
end
defp validate_github_credentials(credentials) do
missing = find_missing_github_credentials(credentials)
if missing == [] do
{:ok, :github}
else
{:error, "Missing GitHub OAuth credentials: #{Enum.join(missing, ", ")}"}
end
end
defp find_missing_google_credentials(credentials) do
[]
|> add_if_missing("Client ID", credentials.client_id)
|> add_if_missing("Client Secret", credentials.client_secret)
end
defp find_missing_apple_credentials(credentials) do
[]
|> add_if_missing("Client ID", credentials.client_id)
|> add_if_missing("Team ID", credentials.team_id)
|> add_if_missing("Key ID", credentials.key_id)
|> add_if_missing("Private Key", credentials.private_key)
end
defp find_missing_github_credentials(credentials) do
[]
|> add_if_missing("Client ID", credentials.client_id)
|> add_if_missing("Client Secret", credentials.client_secret)
end
defp validate_facebook_credentials(credentials) do
missing = find_missing_facebook_credentials(credentials)
if missing == [] do
{:ok, :facebook}
else
{:error, "Missing Facebook OAuth credentials: #{Enum.join(missing, ", ")}"}
end
end
defp find_missing_facebook_credentials(credentials) do
[]
|> add_if_missing("App ID", credentials.app_id)
|> add_if_missing("App Secret", credentials.app_secret)
end
defp add_if_missing(list, field_name, value) do
if value == "" do
[field_name | list]
else
list
end
end
@doc """
Tests OAuth connection for a specific provider.
This function validates the credentials format but does not make actual API calls.
For true connection testing, OAuth flow needs to be initiated through the browser.
## Examples
iex> PhoenixKit.Users.OAuthConfig.test_connection(:google)
{:ok, "Google OAuth credentials are properly formatted"}
"""
def test_connection(provider) when provider in [:google, :apple, :github, :facebook] do
case validate_credentials(provider) do
{:ok, _provider} ->
Logger.info(
"OAuth: #{provider_name(provider)} connection test successful - credentials validated"
)
{:ok,
"#{provider_name(provider)} OAuth credentials are properly formatted. Initiate OAuth flow to test actual connection."}
{:error, reason} ->
Logger.warning("OAuth: #{provider_name(provider)} connection test failed: #{reason}")
{:error, reason}
end
end
defp provider_name(:google), do: "Google"
defp provider_name(:apple), do: "Apple"
defp provider_name(:github), do: "GitHub"
defp provider_name(:facebook), do: "Facebook"
end