Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
malwaredllc
GitHub Repository: malwaredllc/byob
Path: blob/master/web-gui/tests/unit/test_routes.py
1292 views
1
import os
2
import pytest
3
import shutil
4
from flask_login import current_user
5
from buildyourownbotnet import c2
6
from buildyourownbotnet.core.dao import user_dao
7
from buildyourownbotnet.server import SessionThread
8
from buildyourownbotnet.models import db, bcrypt, User
9
from ..conftest import app_client, new_user, login, logout
10
11
# Main routes
12
13
def test_home(app_client):
14
"""
15
Given an app instance,
16
when a GET request is sent to /,
17
check that a HTTP 200 response is returned.
18
"""
19
response = app_client.get('/')
20
assert response.status_code == 200
21
22
def test_docs(app_client):
23
"""
24
Given an app instance,
25
when a GET request is sent to /docs,
26
check that a HTTP 200 response is returned.
27
"""
28
response = app_client.get('/docs')
29
assert response.status_code == 200
30
31
def test_guide(app_client):
32
"""
33
Given an app instance,
34
when a GET request is sent to /guide,
35
check that a HTTP 200 response is returned.
36
"""
37
response = app_client.get('/guide')
38
assert response.status_code == 200
39
40
def test_faq(app_client):
41
"""
42
Given an app instance,
43
when a GET request is sent to /faq,
44
check that a HTTP 200 response is returned.
45
"""
46
response = app_client.get('/faq')
47
assert response.status_code == 200
48
49
# Authentication
50
51
def test_login_valid(app_client, new_user):
52
"""
53
Given a new_user,
54
when a POST request is sent to the /login route with valid credentials,
55
check that the user is correctly logged in with HTTP 200 status.
56
"""
57
response = login(app_client, 'test_user', 'test_password')
58
assert response.status_code == 200
59
assert new_user.is_authenticated is True
60
61
def test_login_invalid(app_client, new_user):
62
"""
63
Given a new_user,
64
when a POST request is sent to the /login route with invalid credentials,
65
check that a 403 forbidden HTTP status is returned.
66
"""
67
response = login(app_client, 'test_user', 'wrong_password')
68
assert response.status_code == 403
69
assert current_user.is_authenticated is False
70
71
def test_logout(app_client, new_user):
72
"""
73
Given a logged in user,
74
when that user sends a GET request to /logout,
75
check that the user is no longer authenticated.
76
"""
77
login(app_client, new_user.username, 'test_password')
78
assert current_user.is_authenticated is True
79
logout(app_client)
80
assert current_user.is_authenticated is False
81
82
def test_sessions_authenticated(app_client, new_user):
83
"""
84
Given a logged in user,
85
when that user sends a GET request to /sessions,
86
check that a HTTP 200 response is returned.
87
"""
88
login(app_client, new_user.username, 'test_password')
89
response = app_client.get('/sessions')
90
assert response.status_code == 200
91
92
def test_sessions_not_authenticated(app_client, new_user):
93
"""
94
Given an unauthenticated user (not logged in),
95
when that user sends a GET request to /sessions,
96
check that a HTTP 302 response is returned, redirecting the user to the login page.
97
"""
98
response = app_client.get('/sessions')
99
assert response.status_code == 302
100
assert '/login' in response.location
101
102
def test_payloads_authenticated(app_client, new_user):
103
"""
104
Given an authenticated user,
105
when that user sends a GET request to /payloads,
106
check that a HTTP 200 response is returned.
107
"""
108
login(app_client, new_user.username, 'test_password')
109
response = app_client.get('/payloads')
110
assert response.status_code == 200
111
112
def test_sessions_not_authenticated(app_client, new_user):
113
"""
114
Given an unauthenticated user (not logged in),
115
when that user sends a GET request to /payloads,
116
check that a HTTP 302 response is returned, redirecting the user to the login page.
117
"""
118
response = app_client.get('/payloads')
119
assert response.status_code == 302
120
assert '/login' in response.location
121
122
def test_files_authenticated(app_client, new_user):
123
"""
124
Given an authenticated user,
125
when that user sends a GET request to /files,
126
check that a HTTP 200 response is returned.
127
"""
128
login(app_client, new_user.username, 'test_password')
129
response = app_client.get('/files')
130
assert response.status_code == 200
131
132
def test_files_not_authenticated(app_client, new_user):
133
"""
134
Given an unauthenticated user (not logged in),
135
when that user sends a GET request to /files,
136
check that a HTTP 302 response is returned, redirecting the user to the login page.
137
"""
138
response = app_client.get('/files')
139
assert response.status_code == 302
140
assert '/login' in response.location
141
142
def test_tasks_authenticated(app_client, new_user):
143
"""
144
Given an authenticated user,
145
when that user sends a GET request to /tasks,
146
check that a HTTP 200 response is returned.
147
"""
148
login(app_client, new_user.username, 'test_password')
149
response = app_client.get('/tasks')
150
assert response.status_code == 200
151
152
def test_tasks_not_authenticated(app_client, new_user):
153
"""
154
Given an unauthenticated user (not logged in),
155
when that user sends a GET request to /tasks,
156
check that a HTTP 302 response is returned, redirecting the user to the login page.
157
"""
158
response = app_client.get('/tasks')
159
assert response.status_code == 302
160
assert '/login' in response.location
161
162
def test_shell_not_authenticated(app_client, new_user, new_session):
163
"""
164
Given an authenticated user and a valid session,
165
when that user sends a GET request to /shell,
166
check that a HTTP 302 response is returned, redirecting the user to the login page.
167
"""
168
response = app_client.get('/shell', data={'session_uid': new_session.uid})
169
assert response.status_code == 302
170
assert '/login' in response.location
171
172
def test_shell_authenticated_valid_session(app_client, new_user, new_session):
173
"""
174
Given an authenticated user and a valid session,
175
when that user sends a GET request to /shell,
176
check that a HTTP 200 response is returned.
177
"""
178
login(app_client, new_user.username, 'test_password')
179
180
# create dummy session
181
dummy_session = SessionThread(id=1, c2=c2, connection=None)
182
dummy_session.info = dict(new_session.serialize())
183
c2.sessions[new_user.username] = {new_session.uid: dummy_session}
184
185
# run test
186
response = app_client.get('/shell', query_string={'session_uid': new_session.uid})
187
assert response.status_code == 200
188
189
def test_shell_authenticated_invalid_session(app_client, new_user):
190
"""
191
Given an unauthenticated user (not logged in),
192
when that user sends a GET request to /shell,
193
check that a HTTP 302 response is returned, redirecting the user to the sessions page.
194
"""
195
login(app_client, new_user.username, 'test_password')
196
197
# no session uid
198
response = app_client.get('/shell')
199
assert response.status_code == 302
200
assert '/sessions' in response.location
201
202
# invalid session uid
203
response = app_client.get('/shell', query_string={'session_uid': 'invalid'})
204
assert response.status_code == 302
205
assert '/sessions' in response.location
206
207
def test_shell_owner_no_sessions(app_client, new_user):
208
"""
209
Given an authenticated user,
210
when a GET request is sent to /shell but the user has no sessions,
211
check that a HTTP 302 response is returned and they are redirected back to the /sessions page.
212
"""
213
login(app_client, new_user.username, 'test_password')
214
c2.sessions[new_user.username] = {}
215
response = app_client.get('/shell', query_string={'session_uid': 'does_not_matter'})
216
assert response.status_code == 302
217
assert '/sessions' in response.location
218
219
def test_shell_wrong_session_owner(app_client, new_user, new_session):
220
"""
221
Given an authenticated user and session,
222
when a GET request is sent to /shell but the session uid belongs to a different user,
223
check that a HTTP 302 response is returned and they are redirected back to the /sessions page.
224
"""
225
login(app_client, new_user.username, 'test_password')
226
227
# create dummy session with different owner
228
dummy_session = SessionThread(id=1, c2=c2, connection=None)
229
dummy_session.info = dict(new_session.serialize())
230
dummy_session.info['owner'] = 'someone_else'
231
c2.sessions[new_user.username] = {new_session.uid: dummy_session}
232
233
# run test
234
response = app_client.get('/shell', query_string={'session_uid': new_session.uid})
235
assert response.status_code == 302
236
237
def test_account(app_client, new_user):
238
"""
239
Given an authenticated user,
240
when a GET request is sent to /account,
241
check that a HTTP 200 response is returned and they are directed to the account page.
242
"""
243
login(app_client, new_user.username, 'test_password')
244
response = app_client.get('/account')
245
assert response.status_code == 200
246
247
def test_register(app_client):
248
"""
249
Given an application instance,
250
when a POST request is sent to /register with valid form data,
251
check that the user is added to the database correctly,
252
the user directories are created in the filesystem properly,
253
and the username is added to the c2 session hashmap properly.
254
"""
255
256
test_username = 'test_user'
257
test_password = 'test_password'
258
try:
259
res = app_client.post('/register',
260
data = {
261
'username': test_username,
262
'password': test_password,
263
'confirm_password': test_password
264
},
265
follow_redirects=True,
266
headers = {"Content-Type":"application/x-www-form-urlencoded"})
267
except Exception as e:
268
pytest.fail("user_dao.add_user returned exception: " + str(e))
269
270
# check user was created in database correctly
271
user = user_dao.get_user(username=test_username)
272
assert user.username == test_username
273
assert bcrypt.check_password_hash(user.password, test_password)
274
275
# check user directory created in filesystem
276
user_dir = os.path.join('./buildyourownbotnet/output/', test_username)
277
assert os.path.isdir(user_dir)
278
279
# check user added to c2 session hashmap
280
assert test_username in c2.sessions
281
282
# clean up
283
User.query.delete()
284
db.session.commit()
285
286
# clean up filesystem
287
shutil.rmtree(user_dir)
288
289