Skip to content

Commit ad4229c

Browse files
committed
Added /campaigns/summary and /campaigns/:id/results endpoints.
1 parent 98d05eb commit ad4229c

File tree

4 files changed

+240
-49
lines changed

4 files changed

+240
-49
lines changed

gophish/api/api.py

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import requests
22

33
from gophish.models import Error
4-
54
'''
65
api.py
76
87
Base API endpoint class that abstracts basic CRUD operations.
98
'''
109

10+
1111
class APIEndpoint(object):
1212
"""
1313
Represents an API endpoint for Gophish, containing common patterns
1414
for CRUD operations.
1515
"""
16+
1617
def __init__(self, api, endpoint=None, cls=None):
1718
""" Creates an instance of the APIEndpoint class.
1819
@@ -25,20 +26,30 @@ def __init__(self, api, endpoint=None, cls=None):
2526
self.endpoint = endpoint
2627
self._cls = cls
2728

28-
def get(self, resource_id=None, resource_action=None):
29+
def get(self,
30+
resource_id=None,
31+
resource_action=None,
32+
resource_cls=None,
33+
single_resource=False):
2934
""" Gets the details for one or more resources by ID
3035
3136
Args:
3237
cls - gophish.models.Model - The resource class
3338
resource_id - str - The endpoint (URL path) for the resource
3439
resource_action - str - An action to perform on the resource
40+
resource_cls - cls - A class to use for parsing, if different than the base resource
41+
single_resource - bool - An override to tell Gophish that even
42+
though we aren't requesting a single resource, we expect a single response object
3543
3644
Returns:
3745
One or more instances of cls parsed from the returned JSON
3846
"""
3947

4048
endpoint = self.endpoint
4149

50+
if not resource_cls:
51+
resource_cls = self._cls
52+
4253
if resource_id:
4354
endpoint = '{}/{}'.format(endpoint, resource_id)
4455

@@ -49,10 +60,10 @@ def get(self, resource_id=None, resource_action=None):
4960
if not response.ok:
5061
return Error.parse(response.json())
5162

52-
if resource_id:
53-
return self._cls.parse(response.json())
63+
if resource_id or single_resource:
64+
return resource_cls.parse(response.json())
5465

55-
return [self._cls.parse(resource) for resource in response.json()]
66+
return [resource_cls.parse(resource) for resource in response.json()]
5667

5768
def post(self, resource):
5869
""" Creates a new instance of the resource.
@@ -61,8 +72,9 @@ def post(self, resource):
6172
resource - gophish.models.Model - The resource instance
6273
6374
"""
64-
response = self.api.execute("POST", self.endpoint, json=(resource.as_dict()))
65-
75+
response = self.api.execute(
76+
"POST", self.endpoint, json=(resource.as_dict()))
77+
6678
if not response.ok:
6779
return Error.parse(response.json())
6880

@@ -74,7 +86,7 @@ def put(self, resource):
7486
Args:
7587
resource - gophish.models.Model - The resource instance
7688
"""
77-
89+
7890
endpoint = self.endpoint
7991

8092
if resource.id:

gophish/api/campaigns.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import json
22

3-
from gophish.models import Campaign, Error
3+
from gophish.models import Campaign, CampaignSummary, CampaignSummaries, CampaignResults, Error
44
from gophish.api import APIEndpoint
55

66

@@ -33,13 +33,27 @@ def delete(self, campaign_id):
3333
def complete(self, campaign_id):
3434
""" Complete an existing campaign (Stop processing events) """
3535

36-
return super(API, self).get(resource_id=campaign_id,
37-
resource_action='complete')
36+
return super(API, self).get(
37+
resource_id=campaign_id, resource_action='complete')
3838

39-
def summary(campaign_id=None):
40-
""" Returns the summary of one or more campaigns. """
41-
raise NotImplementedError
39+
def summary(self, campaign_id=None):
40+
""" Returns the campaign summary """
41+
resource_cls = CampaignSummary
42+
single_resource = False
4243

43-
def results(campaign_id):
44+
if not campaign_id:
45+
resource_cls = CampaignSummaries
46+
single_resource = True
47+
48+
return super(API, self).get(
49+
resource_id=campaign_id,
50+
resource_action='summary',
51+
resource_cls=resource_cls,
52+
single_resource=single_resource)
53+
54+
def results(self, campaign_id):
4455
""" Returns just the results for a given campaign """
45-
raise NotImplementedError
56+
return super(API, self).get(
57+
resource_id=campaign_id,
58+
resource_action='results',
59+
resource_cls=CampaignResults)

gophish/client.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,34 @@
11
import requests
22

3-
from gophish.api import (
4-
campaigns,
5-
groups,
6-
pages,
7-
smtp,
8-
templates)
3+
from gophish.api import (campaigns, groups, pages, smtp, templates)
94

105
DEFAULT_URL = 'http://localhost:3333'
116

7+
128
class GophishClient(object):
139
""" A standard HTTP REST client used by Gophish """
10+
1411
def __init__(self, api_key, host=DEFAULT_URL, **kwargs):
1512
self.api_key = api_key
1613
self.host = host
1714
self._client_kwargs = kwargs
18-
15+
1916
def execute(self, method, path, **kwargs):
2017
""" Executes a request to a given endpoint, returning the result """
2118

2219
url = "{}{}".format(self.host, path)
2320
kwargs.update(self._client_kwargs)
24-
response = requests.request(method, url, params={"api_key": self.api_key}, **kwargs)
21+
response = requests.request(
22+
method, url, params={"api_key": self.api_key}, **kwargs)
2523
return response
2624

25+
2726
class Gophish(object):
28-
def __init__(self, api_key, host=DEFAULT_URL, client=GophishClient, **kwargs):
27+
def __init__(self,
28+
api_key,
29+
host=DEFAULT_URL,
30+
client=GophishClient,
31+
**kwargs):
2932
self.client = client(api_key, host=host, **kwargs)
3033
self.campaigns = campaigns.API(self.client)
3134
self.groups = groups.API(self.client)

0 commit comments

Comments
 (0)