Skip to content

Commit

Permalink
Cloudant 2 (Yelp#207)
Browse files Browse the repository at this point in the history
* clarify var names in test

* help text

* correcting account / pw test verification path

* correcting validation error response

* change detector vars & add cases

* detection tests clean pending verification tests

* all tests clean

* added more key assignment tests

* PR simplifications

* fix capture group

* fix capture group 2
  • Loading branch information
edwarj2 authored and justineyster committed Jan 8, 2020
1 parent 7aad9f3 commit 70f0ce0
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 39 deletions.
45 changes: 28 additions & 17 deletions detect_secrets/plugins/cloudant.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,48 @@ class CloudantDetector(RegexBasedDetector):
opt_dashes = r'(?:--|)'
opt_dot = r'(?:\.|)'
dot = r'\.'
cl_account = r'[0-9a-z\-\_]*'
cl = r'(cloudant|cl|clou)'
cl_account = r'[0-9a-z\-\_]+'
cl = r'(?:cloudant|cl|clou)'
opt_dash_undrscr = r'(?:_|-|)'
opt_api = r'(?:api|)'
cl_key_or_pass = cl + opt_dash_undrscr + r'(?:key|pwd|pw|password|pass|token)'
cl_key_or_pass = opt_api + r'(?:key|pwd|pw|password|pass|token)'
opt_space = r'(?: |)'
assignment = r'(?:=|:|:=|=>)'
cl_secret = r'[0-9a-f]{64}'
cl_pw = r'([0-9a-f]{64})'
cl_api_key = r'([a-z]{24})'
colon = r'\:'
at = r'\@'
http = r'(?:http\:\/\/|https\:\/\/)'
http = r'(?:https?\:\/\/)'
cloudant_api_url = r'cloudant\.com'
denylist = [
RegexBasedDetector.assign_regex_generator(
prefix_regex=cl,
password_keyword_regex=cl_key_or_pass,
password_regex=cl_pw,
),
RegexBasedDetector.assign_regex_generator(
prefix_regex=cl,
password_keyword_regex=cl_key_or_pass,
password_regex=cl_api_key,
),
re.compile(
r'{cl_key_or_pass}{opt_space}{assignment}{opt_space}{opt_quote}{cl_secret}'.format(
cl_key_or_pass=cl_key_or_pass,
opt_quote=opt_quote,
r'{http}{cl_account}{colon}{cl_pw}{at}{cl_account}{dot}{cloudant_api_url}'.format(
http=http,
colon=colon,
cl_account=cl_account,
opt_dash_undrscr=opt_dash_undrscr,
opt_api=opt_api,
opt_space=opt_space,
assignment=assignment,
cl_secret=cl_secret,
), flags=re.IGNORECASE,
cl_pw=cl_pw,
at=at,
dot=dot,
cloudant_api_url=cloudant_api_url,
),
flags=re.IGNORECASE,
),
re.compile(
r'{http}{cl_account}{colon}{cl_secret}{at}{cl_account}{dot}{cloudant_api_url}'.format(
r'{http}{cl_account}{colon}{cl_api_key}{at}{cl_account}{dot}{cloudant_api_url}'.format(
http=http,
colon=colon,
cl_account=cl_account,
cl_secret=cl_secret,
cl_api_key=cl_api_key,
at=at,
dot=dot,
cloudant_api_url=cloudant_api_url,
Expand Down Expand Up @@ -105,7 +116,7 @@ def verify_cloudant_key(hostname, token, potential_secret=None):
request_url = 'https://{hostname}:' \
'{token}' \
'@{hostname}.' \
'cloudant.com/_api/v2'.format(
'cloudant.com'.format(
hostname=hostname,
token=token,
)
Expand Down
64 changes: 42 additions & 22 deletions tests/plugins/cloudant_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
from detect_secrets.plugins.cloudant import get_host

CL_HOST = 'testy_test' # also called user
# only detecting 64 hex
CL_TOKEN = 'abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'
# only detecting 64 hex CL generated password
CL_PW = 'abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234'

# detecting 24 alpha for CL generated API KEYS
CL_API_KEY = 'abcdefghijabcdefghijabcd'


class TestCloudantDetector(object):
Expand All @@ -21,25 +24,42 @@ class TestCloudantDetector(object):
'payload, should_flag',
[
(
'https://{cl_host}:{cl_token}@{cl_host}.cloudant.com"'.format(
cl_host=CL_HOST, cl_token=CL_TOKEN,
'https://{cl_host}:{cl_pw}@{cl_host}.cloudant.com"'.format(
cl_host=CL_HOST, cl_pw=CL_PW,
), True,
),
(
'https://{cl_host}:{cl_pw}@{cl_host}.cloudant.com/_api/v2/'.format(
cl_host=CL_HOST, cl_pw=CL_PW,
), True,
),
(
'https://{cl_host}:{cl_pw}@{cl_host}.cloudant.com/_api/v2/'.format(
cl_host=CL_HOST, cl_pw=CL_PW,
), True,
),
(
'https://{cl_host}:{cl_pw}@{cl_host}.cloudant.com'.format(
cl_host=CL_HOST, cl_pw=CL_PW,
), True,
),
(
'https://{cl_host}:{cl_token}@{cl_host}.cloudant.com/_api/v2/'.format(
cl_host=CL_HOST, cl_token=CL_TOKEN,
'https://{cl_host}:{cl_api_key}@{cl_host}.cloudant.com'.format(
cl_host=CL_HOST, cl_api_key=CL_API_KEY,
), True,
),
(
'https://{cl_host}:{cl_token}.cloudant.com'.format(
cl_host=CL_HOST, cl_token=CL_TOKEN,
'https://{cl_host}:{cl_pw}.cloudant.com'.format(
cl_host=CL_HOST, cl_pw=CL_PW,
), False,
),
('cloudant_password=\'{cl_token}\''.format(cl_token=CL_TOKEN), True),
('cloudant_pw=\'{cl_token}\''.format(cl_token=CL_TOKEN), True),
('cloudant_pw="{cl_token}"'.format(cl_token=CL_TOKEN), True),
('clou_pw = "{cl_token}"'.format(cl_token=CL_TOKEN), True),
('cloudant_password=\'{cl_pw}\''.format(cl_pw=CL_PW), True),
('cloudant_pw=\'{cl_pw}\''.format(cl_pw=CL_PW), True),
('cloudant_pw="{cl_pw}"'.format(cl_pw=CL_PW), True),
('clou_pw = "{cl_pw}"'.format(cl_pw=CL_PW), True),
('cloudant_key = "{cl_api_key}"'.format(cl_api_key=CL_API_KEY), True),
('cloudant_password = "a-fake-tooshort-key"', False),
('cl_api_key = "a-fake-api-key"', False),
],
)
def test_analyze_string(self, payload, should_flag):
Expand All @@ -50,31 +70,31 @@ def test_analyze_string(self, payload, should_flag):

@responses.activate
def test_verify_invalid_secret(self):
cl_api_url = 'https://{cl_host}:{cl_token}@{cl_host}.cloudant.com/_api/v2'.format(
cl_host=CL_HOST, cl_token=CL_TOKEN,
cl_api_url = 'https://{cl_host}:{cl_pw}@{cl_host}.cloudant.com'.format(
cl_host=CL_HOST, cl_pw=CL_PW,
)
responses.add(
responses.GET, cl_api_url,
json={'error': 'Access denied. '}, status=401,
json={'error': 'unauthorized'}, status=401,
)

assert CloudantDetector().verify(
CL_TOKEN,
CL_PW,
'cloudant_host={}'.format(CL_HOST),
) == VerifiedResult.VERIFIED_FALSE

@responses.activate
def test_verify_valid_secret(self):
cl_api_url = 'https://{cl_host}:{cl_token}@{cl_host}.cloudant.com/_api/v2'.format(
cl_host=CL_HOST, cl_token=CL_TOKEN,
cl_api_url = 'https://{cl_host}:{cl_pw}@{cl_host}.cloudant.com'.format(
cl_host=CL_HOST, cl_pw=CL_PW,
)
responses.add(
responses.GET, cl_api_url,
json={'id': 1}, status=200,
)
potential_secret = PotentialSecret('test cloudant', 'test filename', CL_TOKEN)
potential_secret = PotentialSecret('test cloudant', 'test filename', CL_PW)
assert CloudantDetector().verify(
CL_TOKEN,
CL_PW,
'cloudant_host={}'.format(CL_HOST),
potential_secret,
) == VerifiedResult.VERIFIED_TRUE
Expand All @@ -83,13 +103,13 @@ def test_verify_valid_secret(self):
@responses.activate
def test_verify_unverified_secret(self):
assert CloudantDetector().verify(
CL_TOKEN,
CL_PW,
'cloudant_host={}'.format(CL_HOST),
) == VerifiedResult.UNVERIFIED

def test_verify_no_secret(self):
assert CloudantDetector().verify(
CL_TOKEN,
CL_PW,
'no_un={}'.format(CL_HOST),
) == VerifiedResult.UNVERIFIED

Expand Down

0 comments on commit 70f0ce0

Please sign in to comment.