summaryrefslogtreecommitdiff
path: root/addons/web_unsplash/controllers/main.py
diff options
context:
space:
mode:
authorRomain Derie <rde@odoo.com>2018-11-19 14:36:31 +0000
committerJeremy Kersten <jke@odoo.com>2018-11-23 14:51:07 +0000
commit8b1a05d9e09dca317ca38422d75f459a7e1784aa (patch)
treef2e8c5c079e067450f6aa979d84d60eb4eeec11c /addons/web_unsplash/controllers/main.py
parentcd2637cfdf0ec2c5dc2fa2b74b29fdffac822e87 (diff)
[FIX] web_unsplash: don't expose client_id in network
Unsplash CEO asked us to stop exposing our key client side (even if it was only in the browser network and previously allowed by their API team leader). After multiple exchange, it has been negociated that: 1. Our non saas user won't be able to apply for a production key and should prefix they Unsplash application name by 'Odoo:'. Their key will remain in test mode. Indeed, Unsplash won't be able to review every Odoo application and ensure it respects the API terms and it is a real application. 2. Our saas user will query Unsplash with a dedicated enterprise key 3. The documentation should explain it all Task-1911345
Diffstat (limited to 'addons/web_unsplash/controllers/main.py')
-rw-r--r--addons/web_unsplash/controllers/main.py52
1 files changed, 45 insertions, 7 deletions
diff --git a/addons/web_unsplash/controllers/main.py b/addons/web_unsplash/controllers/main.py
index c53c03ba5bf..7a53cd8e115 100644
--- a/addons/web_unsplash/controllers/main.py
+++ b/addons/web_unsplash/controllers/main.py
@@ -9,12 +9,34 @@ import werkzeug.utils
from PIL import Image
from odoo import http, tools, _
from odoo.http import request
+from werkzeug.urls import url_encode
logger = logging.getLogger(__name__)
class Web_Unsplash(http.Controller):
+ def _get_access_key(self):
+ if request.env.user._has_unsplash_key_rights():
+ return request.env['ir.config_parameter'].sudo().get_param('unsplash.access_key')
+ raise werkzeug.exceptions.NotFound()
+
+ def _notify_download(self, url):
+ ''' Notifies Unsplash from an image download. (API requirement)
+ :param url: the download_url of the image to be notified
+
+ This method won't return anything. This endpoint should just be
+ pinged with a simple GET request for Unsplash to increment the image
+ view counter.
+ '''
+ try:
+ if not url.startswith('https://api.unsplash.com/photos/'):
+ raise Exception(_("ERROR: Unknown Unsplash notify URL!"))
+ access_key = self._get_access_key()
+ requests.get(url, params=url_encode({'client_id': access_key}))
+ except Exception as e:
+ logger.exception("Unsplash download notification failed: " + str(e))
+
# ------------------------------------------------------
# add unsplash image url
# ------------------------------------------------------
@@ -22,8 +44,14 @@ class Web_Unsplash(http.Controller):
def save_unsplash_url(self, unsplashurls=None, **kwargs):
"""
unsplashurls = {
- image_id1: image_url1,
- image_id2: image_url2,
+ image_id1: {
+ url: image_url,
+ download_url: download_url,
+ },
+ image_id2: {
+ url: image_url,
+ download_url: download_url,
+ },
.....
}
"""
@@ -82,13 +110,23 @@ class Web_Unsplash(http.Controller):
attachment.generate_access_token()
uploads.extend(attachment.read(['name', 'mimetype', 'checksum', 'res_id', 'res_model', 'access_token', 'url']))
+ # Notifies Unsplash from an image download. (API requirement)
+ self._notify_download(value.get('download_url'))
+
return uploads
- @http.route("/web_unsplash/get_client_id", type='json', auth="user")
- def get_unsplash_client_id(self, **post):
- if request.env.user._has_unsplash_key_rights():
- return request.env['ir.config_parameter'].sudo().get_param('unsplash.access_key')
- raise werkzeug.exceptions.NotFound()
+ @http.route("/web_unsplash/fetch_images", type='json', auth="user")
+ def fetch_unsplash_images(self, **post):
+ access_key = self._get_access_key()
+ app_id = self.get_unsplash_app_id()
+ if not access_key or not app_id:
+ return {'error': 'key_not_found'}
+ post['client_id'] = access_key
+ response = requests.get('https://api.unsplash.com/search/photos/', params=url_encode(post))
+ if response.status_code == requests.codes.ok:
+ return response.json()
+ else:
+ return {'error': response.status_code}
@http.route("/web_unsplash/get_app_id", type='json', auth="public")
def get_unsplash_app_id(self, **post):