mirror of
https://github.com/lingble/chatwoot.git
synced 2025-11-27 00:23:56 +00:00
chore: add github installation steps
This commit is contained in:
@@ -2,18 +2,78 @@ class Github::CallbacksController < ApplicationController
|
||||
include Github::IntegrationHelper
|
||||
|
||||
def show
|
||||
# Log all received parameters for debugging
|
||||
Rails.logger.info("GitHub callback received parameters: #{params.to_unsafe_h}")
|
||||
Rails.logger.info("installation_id present: #{params[:installation_id].present?}")
|
||||
Rails.logger.info("code present: #{params[:code].present?}")
|
||||
Rails.logger.info("setup_action: #{params[:setup_action]}")
|
||||
Rails.logger.info("state present: #{params[:state].present?}")
|
||||
|
||||
if params[:installation_id].present? && params[:code].present?
|
||||
Rails.logger.info('Handling installation with OAuth')
|
||||
# Both installation and OAuth code present - handle both
|
||||
handle_installation_with_oauth
|
||||
elsif params[:installation_id].present?
|
||||
Rails.logger.info('Handling installation only')
|
||||
# Only installation_id present - redirect to OAuth
|
||||
handle_installation
|
||||
else
|
||||
Rails.logger.info('Handling authorization only')
|
||||
# Only OAuth code present - handle authorization
|
||||
handle_authorization
|
||||
end
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("Github callback error: #{e.message}")
|
||||
redirect_to fallback_redirect_uri
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def handle_installation_with_oauth
|
||||
Rails.logger.info("Processing installation with OAuth - installation_id: #{params[:installation_id]}, code: #{params[:code]}")
|
||||
# Handle both installation and OAuth in one go
|
||||
installation_id = params[:installation_id]
|
||||
|
||||
@response = oauth_client.auth_code.get_token(
|
||||
params[:code],
|
||||
redirect_uri: "#{base_url}/github/callback"
|
||||
)
|
||||
|
||||
handle_response(installation_id)
|
||||
end
|
||||
|
||||
def handle_installation
|
||||
Rails.logger.info("Processing installation only - setup_action: #{params[:setup_action]}, installation_id: #{params[:installation_id]}")
|
||||
if params[:setup_action] == 'install'
|
||||
installation_id = params[:installation_id]
|
||||
|
||||
redirect_to build_oauth_url(installation_id)
|
||||
else
|
||||
Rails.logger.error("Unknown setup_action: #{params[:setup_action]}")
|
||||
redirect_to github_integration_settings_url
|
||||
end
|
||||
end
|
||||
|
||||
def handle_authorization
|
||||
Rails.logger.info("Processing authorization only - code: #{params[:code]}")
|
||||
@response = oauth_client.auth_code.get_token(
|
||||
params[:code],
|
||||
redirect_uri: "#{base_url}/github/callback"
|
||||
)
|
||||
|
||||
handle_response
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("Github callback error: #{e.message}")
|
||||
redirect_to github_redirect_uri
|
||||
end
|
||||
|
||||
private
|
||||
def build_oauth_url(installation_id)
|
||||
GlobalConfigService.load('GITHUB_CLIENT_ID', nil)
|
||||
|
||||
# Store installation_id in session for later use
|
||||
session[:github_installation_id] = installation_id
|
||||
|
||||
# For now, redirect to a page that will initiate OAuth with proper account context
|
||||
# This is a temporary solution until we have a proper account-agnostic setup
|
||||
"#{ENV.fetch('FRONTEND_URL', nil)}/app/accounts/1/settings/integrations/github?setup_action=install&installation_id=#{installation_id}"
|
||||
end
|
||||
|
||||
def oauth_client
|
||||
app_id = GlobalConfigService.load('GITHUB_CLIENT_ID', nil)
|
||||
@@ -30,21 +90,37 @@ class Github::CallbacksController < ApplicationController
|
||||
)
|
||||
end
|
||||
|
||||
def handle_response
|
||||
hook = account.hooks.new(
|
||||
access_token: parsed_body['access_token'],
|
||||
status: 'enabled',
|
||||
app_id: 'github',
|
||||
settings: {
|
||||
def handle_response(installation_id = nil)
|
||||
settings = {
|
||||
token_type: parsed_body['token_type'],
|
||||
scope: parsed_body['scope']
|
||||
}
|
||||
|
||||
# Add installation_id from parameter or session
|
||||
if installation_id
|
||||
settings[:installation_id] = installation_id
|
||||
elsif session[:github_installation_id]
|
||||
settings[:installation_id] = session[:github_installation_id]
|
||||
end
|
||||
|
||||
# Use account from state parameter - this should work for both flows now
|
||||
target_account = account
|
||||
|
||||
hook = target_account.hooks.new(
|
||||
access_token: parsed_body['access_token'],
|
||||
status: 'enabled',
|
||||
app_id: 'github',
|
||||
settings: settings
|
||||
)
|
||||
hook.save!
|
||||
|
||||
# Clear session data
|
||||
session.delete(:github_installation_id)
|
||||
|
||||
redirect_to github_redirect_uri
|
||||
rescue StandardError => e
|
||||
Rails.logger.error("Github callback error: #{e.message}")
|
||||
redirect_to github_redirect_uri
|
||||
redirect_to fallback_redirect_uri
|
||||
end
|
||||
|
||||
def account
|
||||
@@ -52,15 +128,30 @@ class Github::CallbacksController < ApplicationController
|
||||
end
|
||||
|
||||
def account_id
|
||||
return unless params[:state]
|
||||
# First try to get from state parameter (OAuth flow)
|
||||
return verify_github_token(params[:state]) if params[:state].present?
|
||||
|
||||
verify_github_token(params[:state])
|
||||
# Fallback to hardcoded account 1 for installation flow (temporary)
|
||||
1
|
||||
end
|
||||
|
||||
def github_redirect_uri
|
||||
"#{ENV.fetch('FRONTEND_URL', nil)}/app/accounts/#{account.id}/settings/integrations/github"
|
||||
end
|
||||
|
||||
def github_integration_settings_url
|
||||
"#{ENV.fetch('FRONTEND_URL', nil)}/app/accounts/1/settings/integrations/github"
|
||||
end
|
||||
|
||||
def fallback_redirect_uri
|
||||
if account_id
|
||||
github_redirect_uri
|
||||
else
|
||||
# Fallback if no account context available
|
||||
"#{ENV.fetch('FRONTEND_URL', nil)}/app/settings/integrations"
|
||||
end
|
||||
end
|
||||
|
||||
def parsed_body
|
||||
@parsed_body ||= @response.response.parsed
|
||||
end
|
||||
|
||||
@@ -62,6 +62,8 @@ class Integrations::App
|
||||
GlobalConfigService.load('SLACK_CLIENT_SECRET', nil).present?
|
||||
when 'linear'
|
||||
GlobalConfigService.load('LINEAR_CLIENT_ID', nil).present?
|
||||
when 'github'
|
||||
GlobalConfigService.load('GITHUB_CLIENT_ID', nil).present? && GlobalConfigService.load('GITHUB_CLIENT_SECRET', nil).present?
|
||||
when 'shopify'
|
||||
shopify_enabled?(account)
|
||||
when 'leadsquared'
|
||||
@@ -87,13 +89,11 @@ class Integrations::App
|
||||
end
|
||||
|
||||
def build_github_action
|
||||
app_id = GlobalConfigService.load('GITHUB_CLIENT_ID', nil)
|
||||
[
|
||||
"#{params[:action]}?client_id=#{app_id}",
|
||||
"redirect_uri=#{self.class.github_integration_url}",
|
||||
"state=#{encode_state}",
|
||||
'scope=repo,read:org'
|
||||
].join('&')
|
||||
GlobalConfigService.load('GITHUB_CLIENT_ID', nil)
|
||||
|
||||
# For GitHub Apps, we need to redirect to the installation page first
|
||||
github_app_name = GlobalConfigService.load('GITHUB_APP_NAME', 'chatwoot-qa')
|
||||
"https://github.com/apps/#{github_app_name}/installations/new"
|
||||
end
|
||||
|
||||
def enabled?(account)
|
||||
|
||||
@@ -387,5 +387,10 @@
|
||||
locked: false
|
||||
description: 'Github client secret'
|
||||
type: secret
|
||||
- name: GITHUB_APP_NAME
|
||||
display_title: 'Github App Name'
|
||||
value:
|
||||
locked: false
|
||||
description: 'Github App name for installation URLs (e.g., "chatwoot-qa")'
|
||||
## ------ End of Github Integration Config ------- #
|
||||
|
||||
|
||||
Reference in New Issue
Block a user