Skip to content

Commit 1e30a15

Browse files
author
Julie B
committed
Add Auth bearer token support
1 parent 9193de7 commit 1e30a15

File tree

2 files changed

+101
-64
lines changed

2 files changed

+101
-64
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ JiraConnector.download_features(
2626
access_key='ASSERTTHAT_ACCESS_KEY',
2727
# Optional can be supplied as environment variable ASSERTTHAT_SECRET_KEY
2828
secret_key='ASSERTTHAT_SECRET_KEY',
29+
# Optional can be supplied as environment variable JIRA_PERSONAL_ACCESS_TOKEN
30+
token='JIRA_PERSONAL_ACCESS_TOKEN',
2931
# Optional - default ./features
3032
output_folder='./features',
3133
#Required for Jira Server only. Omit if using Jira Cloud version
@@ -52,6 +54,8 @@ JiraConnector.upload_report(
5254
access_key='ASSERTTHAT_ACCESS_KEY',
5355
# Optional can be supplied as environment variable ASSERTTHAT_SECRET_KEY
5456
secret_key='ASSERTTHAT_SECRET_KEY',
57+
# Optional can be supplied as environment variable JIRA_PERSONAL_ACCESS_TOKEN
58+
token='JIRA_PERSONAL_ACCESS_TOKEN',
5559
# The name of the run - default 'Test run dd MMM yyyy HH:mm:ss'
5660
run_name= 'Dry Tests Run',
5761
#Required for Jira Server only. Omit if using Jira Cloud version

assertthat_bdd/jira_integration.py

Lines changed: 97 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -8,118 +8,151 @@
88

99
class JiraConnector:
1010

11-
def download_features(project_id, access_key=None, secret_key=None, jira_server_url=None, output_folder='./features/', jql=None, mode='automated', tags=None,
11+
def download_features(project_id, access_key=None, secret_key=None, token=None, jira_server_url=None, output_folder='./features/', jql=None, mode='automated', tags=None,
1212
proxy_uri=None, proxy_username=None, proxy_password=None):
1313

14-
if access_key is None:
15-
if os.environ.get("ASSERTTHAT_ACCESS_KEY") is None:
16-
print("[ERROR] ASSERTTHAT_ACCESS_KEY is missing, should be provided as environment variable or parameter")
17-
else:
14+
# Use environment variable for token if not provided
15+
if token is None:
16+
token = os.environ.get("JIRA_PERSONAL_ACCESS_TOKEN")
17+
18+
# Check for conflicting authentication methods
19+
if token and (access_key or secret_key):
20+
print("[ERROR] Both token and access_key/secret_key are provided. Please use only one authentication method.")
21+
return
22+
23+
# If no token, try to get access_key and secret_key from environment or parameters
24+
if token is None:
25+
if access_key is None:
1826
access_key = os.environ.get("ASSERTTHAT_ACCESS_KEY")
27+
if access_key is None:
28+
print("[ERROR] ASSERTTHAT_ACCESS_KEY is missing, should be provided as environment variable or parameter")
29+
return
1930

20-
if secret_key is None:
21-
if os.environ.get("ASSERTTHAT_SECRET_KEY") is None:
22-
print("[ERROR] ASSERTTHAT_SECRET_KEY is missing, should be provided as environment variable or parameter")
23-
else:
31+
if secret_key is None:
2432
secret_key = os.environ.get("ASSERTTHAT_SECRET_KEY")
33+
if secret_key is None:
34+
print("[ERROR] ASSERTTHAT_SECRET_KEY is missing, should be provided as environment variable or parameter")
35+
return
2536

37+
# Set up the URL and headers
2638
if jira_server_url is None:
27-
path = 'https://bdd.assertthat.app/rest/api/1/project/' + project_id + '/features'
39+
path = f'https://bdd.assertthat.app/rest/api/1/project/{project_id}/features'
2840
else:
29-
path = jira_server_url+"/rest/assertthat/latest/project/" + project_id + "/client/features"
30-
headers = {}
31-
payload = {'mode': mode,
32-
'jql': jql,
33-
'tags': tags
34-
}
41+
path = f'{jira_server_url}/rest/assertthat/latest/project/{project_id}/client/features'
42+
43+
headers = {'X-Atlassian-Token': 'no-check'}
44+
if token:
45+
headers['Authorization'] = f'Bearer {token}'
46+
47+
payload = {
48+
'mode': mode,
49+
'jql': jql,
50+
'tags': tags
51+
}
3552
print('Fetching from: ' + path)
3653

37-
if proxy_uri is None:
54+
# Configure proxies if provided
55+
if proxy_uri:
56+
if proxy_username:
57+
proxy_http = f"http://{proxy_username}:{proxy_password}@{proxy_uri}"
58+
proxy_https = f"https://{proxy_username}:{proxy_password}@{proxy_uri}"
59+
else:
60+
proxy_http = f"http://{proxy_uri}"
61+
proxy_https = f"https://{proxy_uri}"
62+
proxies = {'http': proxy_http, 'https': proxy_https}
63+
else:
3864
proxies = None
3965

40-
elif proxy_uri is not None:
41-
if proxy_username is None:
42-
proxy_http = "http://%s" % (proxy_uri)
43-
proxy_https = "https://%s" % (proxy_uri)
44-
elif proxy_username is not None:
45-
proxy_http = "http://%s:%s@%s" % (proxy_username, proxy_password, proxy_uri)
46-
proxy_https = "https://%s:%s@%s" % (proxy_username, proxy_password, proxy_uri)
47-
proxies = {'http': proxy_http,
48-
'https': proxy_https
49-
}
50-
66+
# Make the request with appropriate authentication
5167
try:
52-
response = requests.get(path, auth=(access_key, secret_key), headers=headers, params=payload,
53-
proxies=proxies)
68+
if token:
69+
response = requests.get(path, headers=headers, params=payload, proxies=proxies)
70+
else:
71+
response = requests.get(path, auth=(access_key, secret_key), headers=headers, params=payload, proxies=proxies)
5472

5573
if response.status_code == 200:
5674
print('Fetched.')
5775
print('Preparing to extract...')
58-
zip = ZipFile(BytesIO(response.content))
59-
infolist = zip.infolist()
60-
zip.extractall(path=output_folder)
61-
print('[INFO] Downloaded ' + str(infolist.__len__()) + ' feature files into "' + output_folder + '"')
76+
zip_file = ZipFile(BytesIO(response.content))
77+
infolist = zip_file.infolist()
78+
zip_file.extractall(path=output_folder)
79+
print('[INFO] Downloaded ' + str(len(infolist)) + ' feature files into "' + output_folder + '"')
80+
else:
81+
print(f"[ERROR] Failed to download features: {response.status_code}")
6282

6383
response.raise_for_status()
6484

6585
except requests.exceptions.HTTPError as errh:
66-
response_content = response.content
67-
print("[ERROR] Failed to download features %s" % (response_content))
68-
86+
print("[ERROR] Failed to download features:", errh)
6987
except requests.exceptions.RequestException as err:
7088
print("[ERROR] Failed to download features", err)
7189

72-
def upload_report(project_id, access_key, secret_key, jira_server_url=None,
90+
def upload_report(project_id, access_key=None, secret_key=None, token=None, jira_server_url=None,
7391
run_name='Test run ' + datetime.datetime.now().strftime("%d %b %Y %H:%M:%S"),
74-
json_report_folder='./reports/', json_report_include_pattern='\.json$', type='cucumber',
92+
json_report_folder='./reports/', json_report_include_pattern=r'\.json$', type='cucumber',
7593
proxy_uri=None, proxy_username=None, proxy_password=None):
7694

95+
# Use environment variable for token if not provided
96+
if token is None:
97+
token = os.environ.get("JIRA_PERSONAL_ACCESS_TOKEN")
98+
99+
# Check for conflicting authentication methods
100+
if token and (access_key or secret_key):
101+
print("[ERROR] Both token and access_key/secret_key are provided. Please use only one authentication method.")
102+
return
103+
104+
# Set up the URL
77105
if jira_server_url is None:
78-
path = 'https://bdd.assertthat.app/rest/api/1/project/' + project_id + '/report'
106+
path = f'https://bdd.assertthat.app/rest/api/1/project/{project_id}/report'
79107
else:
80-
path = jira_server_url + "/rest/assertthat/latest/project/" + project_id + "/client/report"
108+
path = f'{jira_server_url}/rest/assertthat/latest/project/{project_id}/client/report'
81109

82-
if proxy_uri is None:
110+
# Configure proxies if provided
111+
if proxy_uri:
112+
if proxy_username:
113+
proxy_http = f"http://{proxy_username}:{proxy_password}@{proxy_uri}"
114+
proxy_https = f"https://{proxy_username}:{proxy_password}@{proxy_uri}"
115+
else:
116+
proxy_http = f"http://{proxy_uri}"
117+
proxy_https = f"https://{proxy_uri}"
118+
proxies = {'http': proxy_http, 'https': proxy_https}
119+
else:
83120
proxies = None
84121

85-
elif proxy_uri is not None:
86-
if proxy_username is None:
87-
proxy_http = "http://%s" % proxy_uri
88-
proxy_https = "https://%s" % proxy_uri
89-
elif proxy_username is not None:
90-
proxy_http = "http://%s:%s@%s" % (proxy_username, proxy_password, proxy_uri)
91-
proxy_https = "https://%s:%s@%s" % (proxy_username, proxy_password, proxy_uri)
92-
proxies = {'http': proxy_http,
93-
'https': proxy_https
94-
}
122+
headers = {'X-Atlassian-Token': 'no-check'}
123+
if token:
124+
headers['Authorization'] = f'Bearer {token}'
95125

96126
runId = '-1'
97127
for subdir, dirs, files in os.walk(json_report_folder):
98-
print("[INFO] Uploading json reports to AssertThat for %s " % files)
128+
print(f"[INFO] Uploading JSON reports to AssertThat for files: {files}")
99129
for file in files:
100-
if re.search(r"%s" % json_report_include_pattern, file):
130+
if re.search(json_report_include_pattern, file):
101131
report_file = os.path.join(subdir, file)
102132
upload_file = {'file': open(report_file, 'rb')}
103133

104-
headers = {}
105-
payload = {'runName': run_name,
106-
'type': type,
107-
'runId': runId
108-
}
134+
payload = {
135+
'runName': run_name,
136+
'type': type,
137+
'runId': runId
138+
}
109139

110140
try:
111-
response = requests.post(path, auth=(access_key, secret_key), headers=headers, params=payload,
112-
files=upload_file, proxies=proxies)
141+
if token:
142+
response = requests.post(path, headers=headers, params=payload, files=upload_file, proxies=proxies)
143+
else:
144+
response = requests.post(path, auth=(access_key, secret_key), headers=headers, params=payload, files=upload_file, proxies=proxies)
145+
113146
response_content = json.loads(response.content)
114147

115148
if response.status_code == 200:
116-
runId = response_content['runId']
117-
print("[INFO] Uploaded report file %s to AssertThat" % file)
149+
runId = response_content.get('runId', runId) # Update runId if provided in response
150+
print(f"[INFO] Uploaded report file {file} to AssertThat")
118151

119152
response.raise_for_status()
120153

121154
except requests.exceptions.HTTPError as errh:
122-
print("[ERROR] %s while uploading %s" % (response_content['message'], file))
155+
print(f"[ERROR] {response_content.get('message', 'Unknown error')} while uploading {file}")
123156

124157
except requests.exceptions.RequestException as err:
125158
print("[ERROR] Failed to send request", err)

0 commit comments

Comments
 (0)