Skip to content

Commit

Permalink
functions: Use Slack client lib for request validation (#4369)
Browse files Browse the repository at this point in the history
* Use Slack client lib for request validation

* fix bad validation logic

* fix tests

* Add clarifying comment

* Fix lint

* Fix lint, take 2

* rm unused slackeventsapi package
  • Loading branch information
Ace Nassri authored Jul 29, 2020
1 parent 2fdb611 commit 4a25177
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 22 deletions.
16 changes: 4 additions & 12 deletions functions/slack/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@
# limitations under the License.

# [START functions_slack_setup]
import hashlib
import hmac
import os

from flask import jsonify
import googleapiclient.discovery
from slack.signature import SignatureVerifier


kgsearch = googleapiclient.discovery.build(
Expand All @@ -29,19 +28,12 @@


# [START functions_verify_webhook]
# Python 3+ version of https://github.com/slackapi/python-slack-events-api/blob/master/slackeventsapi/server.py
def verify_signature(request):
timestamp = request.headers.get('X-Slack-Request-Timestamp', '')
signature = request.headers.get('X-Slack-Signature', '')
request.get_data() # Decodes received requests into request.data

req = str.encode('v0:{}:'.format(timestamp)) + request.get_data()
request_digest = hmac.new(
str.encode(os.environ['SLACK_SECRET']),
req, hashlib.sha256
).hexdigest()
request_hash = 'v0={}'.format(request_digest)
verifier = SignatureVerifier(os.environ['SLACK_SECRET'])

if not hmac.compare_digest(request_hash, signature):
if not verifier.is_valid_request(request.data, request.headers):
raise ValueError('Invalid request/credentials.')
# [END functions_verify_webhook]

Expand Down
41 changes: 32 additions & 9 deletions functions/slack/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@

import json
import os
import time

import googleapiclient.discovery
import mock
import pytest
from slack.signature import SignatureVerifier

import main

Expand All @@ -28,8 +30,9 @@


class Request(object):
def __init__(self, data=b''):
def __init__(self, data='', headers={}):
self.data = data
self.headers = headers

def get_data(self):
return self.data
Expand All @@ -39,19 +42,28 @@ class TestGCFPySlackSample(object):
def test_verify_signature_request_form_empty(self):
with pytest.raises(ValueError):
request = Request()
request.headers = {}
main.verify_signature(request)

def test_verify_signature_token_incorrect(self):
with pytest.raises(ValueError):
request = Request()
request.headers = {'X-Slack-Signature': '12345'}
request = Request(headers={'X-Slack-Signature': '12345'})
main.verify_signature(request)

def test_verify_web_hook_valid_request(self):
request = Request()
request.body = ''

now = str(int(time.time()))

verifier = SignatureVerifier(os.environ['SLACK_SECRET'])
test_signature = verifier.generate_signature(
timestamp=now,
body=''
)

request.headers = {
'X-Slack-Signature': os.environ['SLACK_TEST_SIGNATURE']
'X-Slack-Request-Timestamp': now,
'X-Slack-Signature': test_signature
}
main.verify_signature(request)

Expand All @@ -77,14 +89,25 @@ def test_kg_search(self):
entities = main.kgsearch.entities.return_value
search = entities.search.return_value
search.execute.return_value = example_response

request = Request()
request.method = 'POST'
request.headers = {
'X-Slack-Signature': os.environ['SLACK_TEST_SIGNATURE']
}
request.form = {
'text': 'lion'
}
request.data = json.dumps(request.form)

now = str(int(time.time()))
verifier = SignatureVerifier(os.environ['SLACK_SECRET'])
test_signature = verifier.generate_signature(
timestamp=now,
body=request.data
)

request.method = 'POST'
request.headers = {
'X-Slack-Request-Timestamp': now,
'X-Slack-Signature': test_signature
}

with mock.patch('main.jsonify', side_effect=json.dumps):
response = main.kg_search(request)
Expand Down
2 changes: 1 addition & 1 deletion functions/slack/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
google-api-python-client==1.10.0
flask==1.1.2
slackeventsapi==2.2.0
slackclient==2.7.3

0 comments on commit 4a25177

Please sign in to comment.