| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- # -*- coding: utf-8 -*-
- # Part of Odoo. See LICENSE file for full copyright and licensing details.
- import requests
- import json
- from odoo import http
- from odoo.http import request
- class GoogleOAuthController(http.Controller):
-
- @http.route('/web/google_oauth_callback', type='http', auth='public', website=True)
- def google_oauth_callback(self, **kw):
- """Handle Google OAuth callback and exchange code for token"""
-
- # Get the authorization code from the callback
- code = kw.get('code')
- state = kw.get('state')
- error = kw.get('error')
-
- if error:
- return f"""
- <html>
- <head><title>OAuth Error</title></head>
- <body>
- <h1>OAuth Error</h1>
- <p>Error: {error}</p>
- <p><a href="/web">Return to Odoo</a></p>
- </body>
- </html>
- """
-
- if not code:
- return """
- <html>
- <head><title>OAuth Error</title></head>
- <body>
- <h1>OAuth Error</h1>
- <p>No authorization code received</p>
- <p><a href="/web">Return to Odoo</a></p>
- </body>
- </html>
- """
-
- try:
- # Get configuration
- client_id = request.env['ir.config_parameter'].sudo().get_param('google_api.client_id')
- client_secret = request.env['ir.config_parameter'].sudo().get_param('google_api.client_secret')
- redirect_uri = request.env['ir.config_parameter'].sudo().get_param('google_api.manual_redirect_uri')
-
- if not all([client_id, client_secret, redirect_uri]):
- raise Exception("Missing OAuth configuration")
-
- # Exchange code for token
- token_url = "https://oauth2.googleapis.com/token"
- token_data = {
- 'client_id': client_id,
- 'client_secret': client_secret,
- 'code': code,
- 'grant_type': 'authorization_code',
- 'redirect_uri': redirect_uri,
- }
-
- response = requests.post(token_url, data=token_data, timeout=30)
-
- if response.status_code != 200:
- raise Exception(f"Token exchange failed: {response.status_code} - {response.text}")
-
- token_info = response.json()
-
- # Store the token information
- access_token = token_info.get('access_token')
- refresh_token = token_info.get('refresh_token')
-
- if not access_token:
- raise Exception("No access token received")
-
- # Store tokens in config parameters (for now, in production you'd want a more secure storage)
- request.env['ir.config_parameter'].sudo().set_param('google_api.access_token', access_token)
- if refresh_token:
- request.env['ir.config_parameter'].sudo().set_param('google_api.refresh_token', refresh_token)
-
- # Test the token by making a simple API call
- headers = {'Authorization': f'Bearer {access_token}'}
- test_response = requests.get(
- 'https://www.googleapis.com/drive/v3/about?fields=user',
- headers=headers,
- timeout=10
- )
-
- if test_response.status_code == 200:
- user_info = test_response.json()
- user_email = user_info.get('user', {}).get('emailAddress', 'Unknown')
-
- return f"""
- <html>
- <head><title>OAuth Success</title></head>
- <body>
- <h1>✅ Google OAuth Success!</h1>
- <p>Successfully connected to Google Drive as: <strong>{user_email}</strong></p>
- <p>Access token has been stored and is ready to use.</p>
- <p><a href="/web#action=google_api.action_google_api_settings">Return to Google API Settings</a></p>
- <script>
- setTimeout(function() {{
- window.close();
- }}, 3000);
- </script>
- </body>
- </html>
- """
- else:
- raise Exception(f"Token validation failed: {test_response.status_code}")
-
- except Exception as e:
- return f"""
- <html>
- <head><title>OAuth Error</title></head>
- <body>
- <h1>❌ OAuth Error</h1>
- <p>Error: {str(e)}</p>
- <p><a href="/web#action=google_api.action_google_api_settings">Return to Google API Settings</a></p>
- </body>
- </html>
- """
|