in src/plugins/scanners/jira.py [0:0]
def scanTicket(KibbleBit, key, u, source, creds, openTickets):
""" Scans a single ticket for activity and people """
dhash = hashlib.sha224( ("%s-%s-%s" % (source['organisation'], source['sourceURL'], key) ).encode('ascii', errors='replace')).hexdigest()
found = True
doc= None
parseIt = False
# the 'domain' var we try to figure out here is used
# for faking email addresses and keep them unique,
# in case JIRA has email visibility turned off.
domain = 'jira'
m = re.search(r"https?://([^/]+)", u)
if m:
domain = m.group(1)
found = KibbleBit.exists('issue', dhash)
if not found:
KibbleBit.pprint("[%s] We've never seen this ticket before, parsing..." % key)
parseIt = True
else:
ticket = KibbleBit.get('issue', dhash)
if ticket['status'] == 'closed' and key in openTickets:
KibbleBit.pprint("[%s] Ticket was reopened, reparsing" % key)
parseIt = True
elif ticket['status'] == 'open' and not key in openTickets:
KibbleBit.pprint("[%s] Ticket was recently closed, parsing it" % key)
parseIt = True
else:
if ( ticket['issueCreator'] == 'unknown@kibble'
or ticket['issueCloser'] == 'unknown@kibble' ): # Gotta redo these!
parseIt = True
KibbleBit.pprint("[%s] Ticket contains erroneous data from a previous scan, reparsing" % key)
# This is just noise!
#KibbleBit.pprint("[%s] Ticket hasn't changed, ignoring..." % key)
if parseIt:
KibbleBit.pprint("[%s] Parsing data from JIRA at %s..." % (key, domain))
queryURL = "%s/rest/api/2/issue/%s?fields=creator,reporter,status,issuetype,summary,assignee,resolutiondate,created,priority,changelog,comment,resolution,votes&expand=changelog" % (u, key)
jiraURL = "%s/browse/%s" % (u, key)
try:
tjson = plugins.utils.jsonapi.get(queryURL, auth = creds)
if not tjson:
KibbleBit.pprint("%s does not exist (404'ed)" % key)
return False
except requests.exceptions.ConnectionError as err:
KibbleBit.pprint("Connection error, skipping this ticket for now!")
return False
st, closer = wasclosed(tjson)
if st and not closer:
KibbleBit.pprint("Closed but no closer??")
closerEmail = None
status = 'closed' if st else 'open'
# Make sure we actually have field data to work with
if not tjson.get('fields') or not tjson['fields'].get('created'):
KibbleBit.pprint("[%s] JIRA response is missing field data, ignoring ticket." % key)
return False
cd = getTime(tjson['fields']['created'])
rd = getTime(tjson['fields']['resolutiondate']) if 'resolutiondate' in tjson['fields'] and tjson['fields']['resolutiondate'] else None
comments = 0
if 'comment' in tjson['fields'] and tjson['fields']['comment']:
comments = tjson['fields']['comment']['total']
assignee = tjson['fields']['assignee'].get('emailAddress', # Try email, fall back to username
tjson['fields']['assignee'].get('name')) if tjson['fields'].get('assignee') else None
creator = tjson['fields']['reporter'].get('emailAddress', # Try email, fall back to username
tjson['fields']['reporter'].get('name')) if tjson['fields'].get('reporter') else None
title = tjson['fields']['summary']
if closer:
#print("Parsing closer")
closerEmail = closer.get('emailAddress', closer.get('name')).replace(" dot ", ".", 10).replace(" at ", "@", 1)
if not '@' in closerEmail:
closerEmail = '%s@%s' % (closerEmail, domain)
displayName = closer.get('displayName', 'Unkown')
if displayName and len(displayName) > 0:
# Add to people db
pid = hashlib.sha1( ("%s%s" % (source['organisation'], closerEmail)).encode('ascii', errors='replace')).hexdigest()
jsp = {
'name': displayName,
'email': closerEmail,
'organisation': source['organisation'],
'id' :pid,
'upsert': True
}
KibbleBit.append('person', jsp)
if creator:
creator = creator.replace(" dot ", ".", 10).replace(" at ", "@", 1)
if not '@' in creator:
creator = '%s@%s' % (creator, domain)
displayName = tjson['fields']['reporter']['displayName'] if tjson['fields']['reporter'] else None
if displayName and len(displayName) > 0:
# Add to people db
pid = hashlib.sha1( ("%s%s" % (source['organisation'], creator)).encode('ascii', errors='replace')).hexdigest()
jsp = {
'name': displayName,
'email': creator,
'organisation': source['organisation'],
'id' :pid,
'upsert': True
}
KibbleBit.append('person', jsp)
if assignee and not '@' in assignee:
assignee = '%s@%s' % (assignee, domain)
jso = {
'id': dhash,
'key': key,
'organisation': source['organisation'],
'sourceID': source['sourceID'],
'url': jiraURL,
'status': status,
'created': cd,
'closed': rd,
'issuetype': 'issue',
'issueCloser': closerEmail,
'createdDate': time.strftime("%Y/%m/%d %H:%M:%S", time.gmtime(cd)),
'closedDate': time.strftime("%Y/%m/%d %H:%M:%S", time.gmtime(rd)) if rd else None,
'changeDate': time.strftime("%Y/%m/%d %H:%M:%S", time.gmtime(rd if rd else cd)),
'assignee': assignee,
'issueCreator': creator,
'comments': comments,
'title': title
}
KibbleBit.append('issue', jso)
return True