ee_auth.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. # -*- coding: utf-8 -*-
  2. """
  3. Init and user authentication in Earth Engine
  4. """
  5. import json
  6. import urllib.request
  7. import urllib.parse
  8. from http.server import BaseHTTPRequestHandler, HTTPServer
  9. import webbrowser
  10. import logging
  11. from qgis.PyQt.QtWidgets import QMessageBox
  12. # fix the warnings/errors messages from 'file_cache is unavailable when using oauth2client'
  13. # https://github.com/googleapis/google-api-python-client/issues/299
  14. logging.getLogger('googleapiclient.discovery_cache').setLevel(logging.ERROR)
  15. SCOPES = [
  16. "https://www.googleapis.com/auth/earthengine",
  17. "https://www.googleapis.com/auth/devstorage.full_control",
  18. "https://www.googleapis.com/auth/accounts.reauth"
  19. ]
  20. class MyHandler(BaseHTTPRequestHandler):
  21. """
  22. Listens to localhost:8085 to get the authentication code
  23. """
  24. def do_GET(self):
  25. parsed = urllib.parse.urlparse(self.path)
  26. MyHandler.auth_code = urllib.parse.parse_qs(parsed.query)['code'][0]
  27. self.send_response(200)
  28. self.send_header('Content-type', 'text/plain')
  29. self.end_headers()
  30. self.wfile.write(bytes("QGIS Google Earth Engine plugin authentication finished successfully.", 'utf-8'))
  31. def authenticate(ee=None):
  32. """
  33. Authenticates Google Earth Engine
  34. """
  35. if ee is None:
  36. import ee
  37. # show a dialog to allow users to start or cancel the authentication process
  38. msg = 'This plugin uses Google Earth Engine API and it looks like it is not yet\n'\
  39. 'authenticated on this machine. You need to have a Google account\n'\
  40. 'registered in Google Earth Engine to continue\n\n'\
  41. 'Click OK to open a web browser and start the authentication process\n'\
  42. 'or click Cancel to stop the authentication process.'
  43. reply = QMessageBox.question(None, 'Google Earth Engine plugin',
  44. msg, QMessageBox.Ok, QMessageBox.Cancel)
  45. if reply == QMessageBox.Cancel:
  46. return False
  47. # start the authentication, getting user login & consent
  48. request_args = {
  49. 'response_type': 'code',
  50. 'client_id': ee.oauth.CLIENT_ID,
  51. 'redirect_uri': "http://localhost:8085/",
  52. 'scope': ' '.join(SCOPES),
  53. 'access_type': 'offline'
  54. }
  55. auth_url = 'https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?' \
  56. + urllib.parse.urlencode(request_args)
  57. webbrowser.open_new(auth_url)
  58. print('Starting Google Earth Engine Authorization ...')
  59. server = HTTPServer(('localhost', 8085), MyHandler)
  60. server.handle_request()
  61. if not MyHandler.auth_code:
  62. print('QGIS EE Plugin authentication failed, can not get authentication code')
  63. return False
  64. # get refresh token
  65. request_args = {
  66. 'code': MyHandler.auth_code,
  67. 'client_id': ee.oauth.CLIENT_ID,
  68. 'client_secret': ee.oauth.CLIENT_SECRET,
  69. 'redirect_uri': "http://localhost:8085/",
  70. 'grant_type': 'authorization_code',
  71. }
  72. data = urllib.parse.urlencode(request_args).encode()
  73. response = urllib.request.urlopen(ee.oauth.TOKEN_URI, data).read().decode()
  74. refresh_token = json.loads(response)['refresh_token']
  75. # write refresh token
  76. client_info = {}
  77. client_info['refresh_token'] = refresh_token
  78. client_info['scopes'] = SCOPES
  79. ee.oauth.write_private_json(ee.oauth.get_credentials_path(), client_info)
  80. print('QGIS EE Plugin authenticated successfully')
  81. return True