Skip to content

Commit cf199be

Browse files
committed
Fixed a whole bunch of stuff.
1 parent d985b38 commit cf199be

File tree

9 files changed

+79
-40
lines changed

9 files changed

+79
-40
lines changed

gophish/api/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .api import APIEndpoint

gophish/api/api.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import requests
22

3+
from gophish.models import Error
4+
35
'''
46
api.py
57
68
Base API endpoint class that abstracts basic CRUD operations.
79
'''
810

9-
class APIEndpoint:
11+
class APIEndpoint(object):
1012
"""
1113
Represents an API endpoint for Gophish, containing common patterns
1214
for CRUD operations.

gophish/api/campaigns.py

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

3-
from gophish.error import Error
4-
from gophish.models import Campaign
3+
from gophish.models import Campaign, Error
54
from gophish.api import APIEndpoint
65

76

87
class API(APIEndpoint):
9-
def __init__(self, api, endpoint='/campaigns'):
8+
def __init__(self, api, endpoint='/api/campaigns'):
109
""" Creates a new instance of the campaigns API """
1110

1211
super(API, self).__init__(api, endpoint=endpoint, cls=Campaign)

gophish/api/groups.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
from gophish.models import Group
2+
from gophish.api import APIEndpoint
23

34
class API(APIEndpoint):
4-
def __init__(self, api, endpoint='/groups'):
5+
def __init__(self, api, endpoint='/api/groups'):
56
super(API, self).__init__(api, endpoint=endpoint, cls=Group)
67

7-
def get(group_id=None):
8+
def get(self, group_id=None):
89
""" Gets one or more groups """
910
return super(API, self).get(resource_id=group_id)
1011

11-
def post(group):
12+
def post(self, group):
1213
""" Creates a new group """
1314
return super(API, self).post(group)
1415

15-
def put(group):
16+
def put(self, group):
1617
""" Edits a group """
1718
return super(API, self).put(group)
1819

19-
def delete(group_id):
20+
def delete(self, group_id):
2021
""" Deletes a group by ID """
2122
return super(API, self).put(group_id)

gophish/api/pages.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from gophish.api import APIEndpoint
33

44
class API(APIEndpoint):
5-
def __init__(self, api, endpoint='/pages'):
5+
def __init__(self, api, endpoint='/api/pages'):
66
super(API, self).__init__(api, endpoint=endpoint, cls=Page)
77

88
def get(self, page_id=None):

gophish/api/smtp.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from gophish.api import APIEndpoint
21
from gophish.models import SMTP
2+
from gophish.api import APIEndpoint
33

44
class API(APIEndpoint):
5-
def __init__(self, api, endpoint='/smtp'):
5+
def __init__(self, api, endpoint='/api/smtp'):
66
super(API, self).__init__(api, endpoint=endpoint, cls=SMTP)
77

88
def get(self, smtp_id=None):

gophish/api/templates.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from gophish.api import APIEndpoint
33

44
class API(APIEndpoint):
5-
def __init__(self, api, endpoint='/templates'):
5+
def __init__(self, api, endpoint='/api/templates'):
66
super(API, self).__init__(api, endpoint=endpoint, cls=Template)
77

88
def get(self, template_id=None):

gophish/client.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,33 @@
11
import requests
22

3+
from gophish.api import (
4+
campaigns,
5+
groups,
6+
pages,
7+
smtp,
8+
templates)
9+
310
DEFAULT_URL = 'http://localhost:3333'
411

5-
class Gophish:
6-
def __init__(self, api_key, host=DEFAULT_URL):
12+
class GophishClient(object):
13+
""" A standard HTTP REST client used by Gophish """
14+
def __init__(self, api_key, host=DEFAULT_URL, **kwargs):
715
self.api_key = api_key
816
self.host = host
17+
self._kwargs = kwargs
918

10-
def __execute(path, method, data=None):
19+
def execute(self, method, path, data=None):
1120
""" Executes a request to a given endpoint, returning the result """
1221

13-
url = "{}/{}".format(this.host, path)
14-
response = requests.request(method, url, json=data)
15-
return response.json()
22+
url = "{}{}".format(self.host, path)
23+
response = requests.request(method, url, params={"api_key": self.api_key}, json=data, **self._kwargs)
24+
return response
25+
26+
class Gophish(object):
27+
def __init__(self, api_key, host=DEFAULT_URL, client=GophishClient, **kwargs):
28+
self.client = client(api_key, host=host, **kwargs)
29+
self.campaigns = campaigns.API(self.client)
30+
self.groups = groups.API(self.client)
31+
self.pages = pages.API(self.client)
32+
self.smtp = smtp.API(self.client)
33+
self.templates = templates.API(self.client)

gophish/models.py

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
from datetime import datetime
2+
23
import json as _json
4+
import dateutil.parser
5+
6+
def parse_date(datestr):
7+
""" Parses an ISO 8601 formatted date from Gophish """
8+
return dateutil.parser.parse(datestr)
39

410
class Model(object):
511
def __init__(self):
@@ -51,36 +57,31 @@ class Result(Model):
5157
'position': None, 'ip': None, 'latitude': None, 'longitude': None,
5258
'status': None}
5359

54-
def __init__(**kwargs):
60+
def __init__(self, **kwargs):
5561
for key, default in Result.__valid_properties.items():
5662
setattr(self, key, kwargs.get(key, default))
5763

5864
@classmethod
5965
def parse(cls, json):
60-
raise NotImplementedError
66+
result = cls()
67+
for key, val in json.items():
68+
if key in cls.__valid_properties:
69+
setattr(result, key, val)
6170

6271

6372
class TimelineEntry(object):
64-
__valid_properties = ['email', 'time', 'message', 'details']
65-
66-
def __init__(entry):
67-
for key, default in TimelineEntry.__valid_properties.items():
68-
setattr(self, key, kwargs.get(key, default))
73+
__valid_properties = {'email': None, 'time': None, 'message': None, 'details': None}
6974

7075
@classmethod
7176
def parse(cls, json):
7277
entry = cls()
7378
for key, val in json.items():
74-
if key == 'details':
79+
if key == 'details' and val != "":
7580
details = _json.loads(val)
7681
setattr(entry, key, details)
7782
elif key in cls.__valid_properties:
7883
setattr(entry, key, val)
7984

80-
@classmethod
81-
def parse(cls, json):
82-
raise NotImplementedError
83-
8485

8586
class User(Model):
8687
""" User contains the attributes for a member of a group
@@ -89,7 +90,7 @@ class User(Model):
8990
'id': None, 'first_name': None, 'last_name': None, 'email': None,
9091
'position': None}
9192

92-
def __init__(**kwargs):
93+
def __init__(self, **kwargs):
9394
for key, default in User.__valid_properties.items():
9495
setattr(self, key, kwargs.get(key, default))
9596

@@ -104,7 +105,7 @@ class Group(Model):
104105
'id': None, 'name': None, 'modified_date': datetime.now(),
105106
'targets': []}
106107

107-
def __init__(**kwargs):
108+
def __init__(self, **kwargs):
108109
for key, default in Group.__valid_properties.items():
109110
setattr(self, key, kwargs.get(key, default))
110111

@@ -117,7 +118,7 @@ def parse(cls, json):
117118
setattr(group, key, users)
118119
elif key == 'modified_date':
119120
setattr(group, key, parse_date(val))
120-
elif key in Group.__valid_properties:
121+
elif key in cls.__valid_properties:
121122
setattr(group, key, val)
122123
return group
123124

@@ -128,7 +129,7 @@ class SMTP(Model):
128129
'from_address': None, 'ignore_cert_errors' : False,
129130
'modified_date': datetime.now()}
130131

131-
def __init__(**kwargs):
132+
def __init__(self, **kwargs):
132133
for key, default in SMTP.__valid_properties.items():
133134
setattr(self, key, kwargs.get(key, default))
134135

@@ -138,7 +139,7 @@ def parse(cls, json):
138139
for key, val in json.items():
139140
if key == 'modified_date':
140141
setattr(smtp, key, parse_date(val))
141-
elif key in SMTP.__valid_properties:
142+
elif key in cls.__valid_properties:
142143
setattr(smtp, key, val)
143144
return smtp
144145

@@ -148,7 +149,7 @@ class Template(Model):
148149
'id': None, 'name': None, 'text': None, 'html': None,
149150
'modified_date': datetime.now(), 'subject': None, 'attachments': []}
150151

151-
def __init__(**kwargs):
152+
def __init__(self, **kwargs):
152153
for key, default in Template.__valid_properties.items():
153154
setattr(self, key, kwargs.get(key, default))
154155

@@ -162,7 +163,7 @@ def parse(cls, json):
162163
attachments = [
163164
Attachment.parse(attachment) for attachment in val]
164165
setattr(template, key, attachments)
165-
elif key in Template.__valid_properties:
166+
elif key in cls.__valid_properties:
166167
setattr(template, key, val)
167168

168169

@@ -172,7 +173,7 @@ class Page(Model):
172173
'capture_credentials': False, 'capture_passwords': False,
173174
'redirect_url': None}
174175

175-
def __init__(**kwargs):
176+
def __init__(self, **kwargs):
176177
for key, default in Page.__valid_properties.items():
177178
setattr(self, key, kwargs.get(key, default))
178179

@@ -182,5 +183,22 @@ def parse(cls, json):
182183
for key, val in json.items():
183184
if key == 'modified_date':
184185
setattr(page, key, parse_date(val))
185-
elif key in Page.__valid_properties:
186+
elif key in cls.__valid_properties:
186187
setattr(page, key, val)
188+
189+
class Attachment(Model):
190+
__valid_properties = {}
191+
192+
@classmethod
193+
def parse(cls, json):
194+
return cls()
195+
196+
class Error(Model):
197+
__valid_properties = {'message', 'success', 'data'}
198+
199+
@classmethod
200+
def parse(cls, json):
201+
error = cls()
202+
for key, val in json.items():
203+
if key in cls.__valid_properties:
204+
setattr(error, key, val)

0 commit comments

Comments
 (0)