Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authentication error #64

Merged
merged 8 commits into from Aug 5, 2020
7 changes: 5 additions & 2 deletions Map.py
Expand Up @@ -3,13 +3,16 @@
functions to use GEE within Qgis python script
"""
import math
import json
import ee

from qgis.core import QgsCoordinateReferenceSystem, QgsCoordinateTransform, Qgis, QgsProject, QgsPointXY, QgsRectangle
from qgis.core import QgsCoordinateReferenceSystem, QgsCoordinateTransform, QgsProject, QgsPointXY, QgsRectangle
from qgis.utils import iface

import ee_plugin.utils
import ee_plugin.ee_auth

# init the Google Earth Engine user authorization system
ee_plugin.ee_auth.init()


def addLayer(eeObject, visParams=None, name=None, shown=True, opacity=1.0):
Expand Down
8 changes: 7 additions & 1 deletion README.md
Expand Up @@ -41,9 +41,15 @@ A: Go to http://code.earthengine.google.com and make sure you can access code ed
#### Alpha 0.2 (Q3 2020)
- [x] Upgrade EE library to 0.1.224 (Windows, Linux, maxOS)

#### Alpha 0.3 (Q4 2020)
#### Alpha 0.3 (Q3 2020)
- [x] EE raster layer inspector
- [x] Show some useful EE properties (bands, value types) in QGIS layer properties dialog
- [x] Fix GEE url authentication function if the credentials is not exists #63
- [x] Fix crash if the authentication dialog is cancelled or not filled by the user
- [x] Init the Google Earth Engine user authorization system only when the user is going to use the plugin
- [x] Fixed the authentication dialog when the url shortener doesn't work by any reason #66

#### Alpha 0.4 (Q4 2020)
- [ ] EE vector layer inspector
- [ ] EE raster collection layer inspector
- [ ] Make print(ee_object) more user-friendly, without requiring getInfo(), maybe async
Expand Down
41 changes: 29 additions & 12 deletions ee_auth.py
Expand Up @@ -2,6 +2,8 @@
"""
Init and user authentication in Earth Engine
"""
import os
import hashlib
import urllib.request
import webbrowser
from qgis.PyQt.QtWidgets import QInputDialog
Expand All @@ -18,18 +20,29 @@ def init():
try:
ee.Initialize()
except ee.ee_exception.EEException:
authenticate()
ee.Initialize() # retry initialization once the user logs in
if authenticate():
ee.Initialize() # retry initialization once the user logs in
else:
print('\nGoogle Earth Engine authorization failed!\n')


def tiny_url(url):
apiurl = "http://tinyurl.com/api-create.php?url="
tinyurl = urllib.request.urlopen(apiurl + url).read()
return tinyurl.decode("utf-8")
try:
apiurl = "http://tinyurl.com/api-create.php?url="
tinyurl = urllib.request.urlopen(apiurl + url).read()
return True, tinyurl.decode("utf-8")
except:
return False, url


def authenticate():
auth_url = ee.oauth.get_authorization_url()
# PKCE. Generates a challenge that the server will use to ensure that the
# auth_code only works with our verifier. https://tools.ietf.org/html/rfc7636
code_verifier = ee.oauth._base64param(os.urandom(32))
code_challenge = ee.oauth._base64param(hashlib.sha256(code_verifier).digest())
auth_url = ee.oauth.get_authorization_url(code_challenge)
tiny_url_ok, auth_url = tiny_url(auth_url)

webbrowser.open_new(auth_url)

print('\nGoogle Earth Engine Authorization:\n'
Expand All @@ -38,11 +51,15 @@ def authenticate():

token, ok = QInputDialog.getText(None, 'Authorization',
'Google Earth Engine Python is not detected on this machine.\n'
'This plugin uses Google Earth Engine Python API and requires users \n'
'to be authorized, please follow the instructions in the opened web page\n'
'and paste the resulting auth token here.\n\n'
'If the web page does not open automatically, visit the following link manually:\n'
'URL: ' + tiny_url(auth_url))
'This plugin uses Google Earth Engine Python API and requires\n'
'users to be authorized, please follow the instructions in the\n'
'opened web page and paste the resulting auth token here.\n\n'
'If the web page does not open automatically,\n'
+ ('visit the following link manually:\nURL: {}'.format(auth_url)
if tiny_url_ok else 'visit the link that appears in the python console'))

if ok and token:
ee.oauth._obtain_and_write_token(token.strip())
ee.oauth._obtain_and_write_token(token.strip(), code_verifier)
return True
else:
return False
4 changes: 1 addition & 3 deletions ee_plugin.py
Expand Up @@ -21,14 +21,12 @@
from qgis.core import QgsProject

import ee
import ee_plugin.ee_auth
from ee_plugin import utils
from ee_plugin import provider

ee_plugin.ee_auth.init()

version_checked = False


class GoogleEarthEnginePlugin(object):
"""QGIS Plugin Implementation."""

Expand Down
3 changes: 2 additions & 1 deletion provider.py
Expand Up @@ -8,7 +8,7 @@

import ee

from ee_plugin import Map, utils
from ee_plugin import utils

BAND_TYPES = {
'int8': Qgis.Int16,
Expand Down Expand Up @@ -100,6 +100,7 @@ def sourceDataType(self, band_no):

def identify(self, point, format, boundingBox=None, width=None, height=None, dpi=None):
# TODO: speed-up, extend this to maintain cache of visible image, update cache on-the-fly when needed
from ee_plugin import Map

point = utils.geom_to_geo(point)

Expand Down
3 changes: 0 additions & 3 deletions utils.py
Expand Up @@ -14,9 +14,6 @@
import ee
import ee_plugin

# from ee_plugin.provider import EarthEngineRasterDataProvider
from ee_plugin import Map


def get_ee_image_url(image):
map_id = ee.data.getMapId({'image': image})
Expand Down