forked from PortSwigger/python-scripter
-
Notifications
You must be signed in to change notification settings - Fork 0
/
models.py
202 lines (156 loc) · 6.18 KB
/
models.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
from abc import abstractmethod
from time import time
from java.beans import PropertyChangeSupport, PropertyChangeEvent
import sys
import traceback
DEFAULT_SCRIPT = '''# Recommended to use the pyscripter-er base script found here https://github.com/lanmaster53/pyscripter-er
# to be placed into the python environment directory
# from pyscripterer import BaseScript as Script
# args = [extender, callbacks, helpers, toolFlag, messageIsRequest, messageInfo, macroItems]
# script = Script(*args)
# script.help()
'''
class ObservableCollection(object):
ITEM_ADDED = 2
ITEM_REMOVED = 1
def __init__(self):
self.listeners = []
@abstractmethod
def add(self, obj): # implemented by subclass
raise NotImplementedError()
@abstractmethod
def remove(self, obj): # implemented by subclass
raise NotImplementedError()
def add_listener(self, listener):
self.listeners.append(listener)
def remove_listener(self, listener):
self.listeners.remove(listener)
def _fireChangedEvent(self, type, obj):
for listener in self.listeners:
listener.collection_changed(self, type, obj)
class JavaBean(object):
def __init__(self):
self._changeSupport = None
def addPropertyChangeListener(self, *args):
if not self._changeSupport:
self._changeSupport = PropertyChangeSupport(self)
self._changeSupport.addPropertyChangeListener(*args)
def removePropertyChangeListener(self, *args):
if self._changeSupport:
self._changeSupport.removePropertyChangeListener(*args)
def firePropertyChange(self, propertyName, oldValue, newValue):
if self._changeSupport:
event = PropertyChangeEvent(self, propertyName, oldValue, newValue)
self._changeSupport.firePropertyChange(event)
def getPropertyChangeListeners(self, *args):
if self._changeSupport:
return self._changeSupport.getPropertyChangeListeners(*args)
return []
def hasListeners(self, *args):
if self._changeSupport:
return self._changeSupport.hasListeners(*args)
return False
class ScriptCollection(ObservableCollection):
def __init__(self):
super(ScriptCollection, self).__init__()
self.scripts = []
def add(self, script):
self.scripts.append(script)
self._fireChangedEvent(ObservableCollection.ITEM_ADDED, script)
def remove(self, script):
self.scripts.remove(script)
self._fireChangedEvent(ObservableCollection.ITEM_REMOVED, script)
def to_dict(self):
return {
'created_at': int(time()),
'scripts': [script.to_dict() for script in self.scripts]
}
def from_dict(self, val, callbacks, helpers, extender):
for script in val['scripts']:
self.add(Script.from_dict(script, callbacks, helpers, extender))
def __getitem__(self, index):
return self.scripts[index]
def __len__(self):
return len(self.scripts)
def __iter__(self):
return self.scripts
def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo, macroItems=[]):
for script in self.scripts:
script.processHttpMessage(toolFlag, messageIsRequest, messageInfo, macroItems)
class Script(JavaBean):
def __init__(self, extender, callbacks, helpers, title, enabled=False, content=DEFAULT_SCRIPT):
super(Script, self).__init__()
self.title = title
self.enabled = enabled
self.callbacks = callbacks
self.helpers = helpers
self.extender = extender
self.content = content
self.stderr = sys.stderr
self.stdout = sys.stdout
self.state = dict()
self._code = None
self._compiled_content = content
self._compilation_error = ''
self._is_compiled = False
def to_dict(self):
fields = ['title', 'enabled', 'content']
return { field: getattr(self, field) for field in fields}
def compile(self):
try:
self._code = None
self._compiled_content = self.content
self._code = compile(self.content, '<string>', 'exec')
self.is_compiled = True
except:
self.is_compiled = False
self._compilation_error = traceback.format_exc()
self.firePropertyChange(Script.Properties.COMPILATION_ERROR, '', self._compilation_error)
def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo, macroItems=[]):
if self.enabled and self._code:
locals_ = {}
globals_ = {'extender': self.extender,
'callbacks': self.callbacks,
'helpers': self.helpers,
'toolFlag': toolFlag,
'messageIsRequest': messageIsRequest,
'messageInfo': messageInfo,
'macroItems': macroItems,
'state': self.state
}
oldstderr = sys.stderr
oldstdout = sys.stdout
sys.stdout = self.stdout
sys.stderr = self.stderr
try:
exec(self._code, globals_, locals_)
except:
self.stderr.write(traceback.format_exc())
finally:
sys.stdout = oldstdout
sys.stderr = oldstderr
@property
def requires_compile(self):
return self.content != self._compiled_content
@property
def compilation_error(self):
return self._compile_error
@property
def is_compiled(self):
return self._is_compiled
@is_compiled.setter
def is_compiled(self, val):
old_val = self._is_compiled
self._is_compiled = val
self.firePropertyChange(Script.Properties.IS_COMPILED, old_val, self._is_compiled)
@classmethod
def from_dict(cls, val, callbacks, helpers, extender):
return Script(extender,
callbacks,
helpers,
val['title'],
val['enabled'],
val['content'])
class Properties:
COMPILATION_ERROR = 'compilation_error'
IS_COMPILED = 'is_compiled'