main.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. # -*- coding: utf-8 -*-
  2. # Part of Odoo. See LICENSE file for full copyright and licensing details.
  3. import requests
  4. import json
  5. from odoo import http
  6. from odoo.http import request
  7. class GoogleOAuthController(http.Controller):
  8. @http.route('/web/google_oauth_callback', type='http', auth='public', website=True)
  9. def google_oauth_callback(self, **kw):
  10. """Handle Google OAuth callback and exchange code for token"""
  11. # Get the authorization code from the callback
  12. code = kw.get('code')
  13. state = kw.get('state')
  14. error = kw.get('error')
  15. if error:
  16. return f"""
  17. <html>
  18. <head><title>OAuth Error</title></head>
  19. <body>
  20. <h1>OAuth Error</h1>
  21. <p>Error: {error}</p>
  22. <p><a href="/web">Return to Odoo</a></p>
  23. </body>
  24. </html>
  25. """
  26. if not code:
  27. return """
  28. <html>
  29. <head><title>OAuth Error</title></head>
  30. <body>
  31. <h1>OAuth Error</h1>
  32. <p>No authorization code received</p>
  33. <p><a href="/web">Return to Odoo</a></p>
  34. </body>
  35. </html>
  36. """
  37. try:
  38. # Get configuration
  39. client_id = request.env['ir.config_parameter'].sudo().get_param('google_api.client_id')
  40. client_secret = request.env['ir.config_parameter'].sudo().get_param('google_api.client_secret')
  41. redirect_uri = request.env['ir.config_parameter'].sudo().get_param('google_api.manual_redirect_uri')
  42. if not all([client_id, client_secret, redirect_uri]):
  43. raise Exception("Missing OAuth configuration")
  44. # Exchange code for token
  45. token_url = "https://oauth2.googleapis.com/token"
  46. token_data = {
  47. 'client_id': client_id,
  48. 'client_secret': client_secret,
  49. 'code': code,
  50. 'grant_type': 'authorization_code',
  51. 'redirect_uri': redirect_uri,
  52. }
  53. response = requests.post(token_url, data=token_data, timeout=30)
  54. if response.status_code != 200:
  55. raise Exception(f"Token exchange failed: {response.status_code} - {response.text}")
  56. token_info = response.json()
  57. # Store the token information
  58. access_token = token_info.get('access_token')
  59. refresh_token = token_info.get('refresh_token')
  60. if not access_token:
  61. raise Exception("No access token received")
  62. # Store tokens in config parameters (for now, in production you'd want a more secure storage)
  63. request.env['ir.config_parameter'].sudo().set_param('google_api.access_token', access_token)
  64. if refresh_token:
  65. request.env['ir.config_parameter'].sudo().set_param('google_api.refresh_token', refresh_token)
  66. # Test the token by making a simple API call
  67. headers = {'Authorization': f'Bearer {access_token}'}
  68. test_response = requests.get(
  69. 'https://www.googleapis.com/drive/v3/about?fields=user',
  70. headers=headers,
  71. timeout=10
  72. )
  73. if test_response.status_code == 200:
  74. user_info = test_response.json()
  75. user_email = user_info.get('user', {}).get('emailAddress', 'Unknown')
  76. return f"""
  77. <html>
  78. <head><title>OAuth Success</title></head>
  79. <body>
  80. <h1>✅ Google OAuth Success!</h1>
  81. <p>Successfully connected to Google Drive as: <strong>{user_email}</strong></p>
  82. <p>Access token has been stored and is ready to use.</p>
  83. <p><a href="/web#action=google_api.action_google_api_settings">Return to Google API Settings</a></p>
  84. <script>
  85. setTimeout(function() {{
  86. window.close();
  87. }}, 3000);
  88. </script>
  89. </body>
  90. </html>
  91. """
  92. else:
  93. raise Exception(f"Token validation failed: {test_response.status_code}")
  94. except Exception as e:
  95. return f"""
  96. <html>
  97. <head><title>OAuth Error</title></head>
  98. <body>
  99. <h1>❌ OAuth Error</h1>
  100. <p>Error: {str(e)}</p>
  101. <p><a href="/web#action=google_api.action_google_api_settings">Return to Google API Settings</a></p>
  102. </body>
  103. </html>
  104. """