1 package com.jsql.view.swing.panel.address;
2
3 import com.jsql.model.injection.strategy.AbstractStrategy;
4 import com.jsql.model.injection.strategy.StrategyError;
5 import com.jsql.model.injection.engine.model.Engine;
6 import com.jsql.model.injection.engine.model.yaml.Method;
7 import com.jsql.util.CookiesUtil;
8 import com.jsql.util.I18nUtil;
9 import com.jsql.util.LogLevelUtil;
10 import com.jsql.util.ParameterUtil;
11 import com.jsql.view.swing.panel.PanelAddressBar;
12 import com.jsql.view.swing.text.JToolTipI18n;
13 import com.jsql.view.swing.util.I18nViewUtil;
14 import com.jsql.view.swing.util.MediatorHelper;
15 import com.jsql.view.swing.util.UiUtil;
16 import org.apache.commons.lang3.StringUtils;
17 import org.apache.logging.log4j.LogManager;
18 import org.apache.logging.log4j.Logger;
19
20 import javax.swing.*;
21 import java.awt.*;
22 import java.awt.event.MouseAdapter;
23 import java.awt.event.MouseEvent;
24 import java.net.MalformedURLException;
25 import java.net.URI;
26 import java.net.URISyntaxException;
27 import java.util.AbstractMap;
28 import java.util.Arrays;
29 import java.util.Locale;
30 import java.util.concurrent.atomic.AtomicReference;
31 import java.util.regex.Pattern;
32 import java.util.stream.Stream;
33 import java.util.stream.StreamSupport;
34
35 public class PanelTrailingAddress extends JPanel {
36
37 private static final Logger LOGGER = LogManager.getRootLogger();
38
39 public static final String MENU_STRATEGY = "menuStrategy";
40 public static final String ITEM_RADIO_STRATEGY_ERROR = "itemRadioStrategyError";
41 public static final String MENU_VENDOR = "menuVendor";
42 public static final String ITEM_RADIO_VENDOR = "itemRadioVendor";
43 public static final String PARAM_AUTO = "Param auto";
44
45 private JMenu itemRadioStrategyError;
46
47 private final JLabel labelTarget = new JLabel(UiUtil.TARGET.getIcon(), SwingConstants.LEFT);
48 private final JLabel labelEngine = new JLabel(UiUtil.ARROW_DOWN.getIcon(), SwingConstants.LEFT);
49 private final JLabel labelStrategy = new JLabel(UiUtil.ARROW_DOWN.getIcon(), SwingConstants.LEFT);
50 private final JPopupMenu popupMenuTargets = new JPopupMenu();
51 private ButtonGroup groupRadio = new ButtonGroup();
52 private final JPopupMenu popupMenuEngines = new JPopupMenu();
53 private final JPopupMenu popupMenuStrategies = new JPopupMenu();
54
55 private final ButtonGroup groupStrategy = new ButtonGroup();
56 public static final String PREFIX_NAME_ERROR = "itemRadioError";
57 private static final String I18N_TOOLTIP_STRATEGY = "STRATEGY_%s_TOOLTIP";
58
59
60
61
62 private final JProgressBar loader;
63
64
65
66
67 public final ButtonStart buttonStart = new ButtonStart();
68
69 public PanelTrailingAddress(PanelAddressBar panelAddressBar) {
70 this.buttonStart.addActionListener(new ActionStart(panelAddressBar));
71 this.setOpaque(false);
72 this.setBorder(null);
73 this.labelStrategy.setText("Strategy auto");
74 this.labelStrategy.setName(PanelTrailingAddress.MENU_STRATEGY);
75
76 for (final AbstractStrategy strategy: MediatorHelper.model().getMediatorStrategy().getStrategies()) {
77 var nameStrategy = strategy.getName().toUpperCase(Locale.ROOT);
78 JMenuItem itemRadioStrategy;
79 if (strategy == MediatorHelper.model().getMediatorStrategy().getError()) {
80 itemRadioStrategy = new JMenu(strategy.toString());
81 this.itemRadioStrategyError = (JMenu) itemRadioStrategy;
82 itemRadioStrategy.getComponent().setName(PanelTrailingAddress.ITEM_RADIO_STRATEGY_ERROR);
83 } else {
84 var atomicTooltip = new AtomicReference<>(new JToolTipI18n(
85 I18nUtil.valueByKey(String.format(PanelTrailingAddress.I18N_TOOLTIP_STRATEGY, nameStrategy))
86 ));
87 itemRadioStrategy = new JRadioButtonMenuItem(strategy.toString()) {
88 @Override
89 public JToolTip createToolTip() {
90 atomicTooltip.set(new JToolTipI18n(
91 I18nUtil.valueByKey(
92 String.format(PanelTrailingAddress.I18N_TOOLTIP_STRATEGY, nameStrategy)
93 )
94 ));
95 return atomicTooltip.get();
96 }
97 };
98 I18nViewUtil.addComponentForKey(
99 String.format(PanelTrailingAddress.I18N_TOOLTIP_STRATEGY, nameStrategy),
100 atomicTooltip.get()
101 );
102 itemRadioStrategy.getComponent().setName("itemRadioStrategy" + strategy);
103 itemRadioStrategy.addActionListener(actionEvent -> {
104 this.labelStrategy.setText(strategy.toString());
105 MediatorHelper.model().getMediatorStrategy().setStrategy(strategy);
106 });
107 this.groupStrategy.add(itemRadioStrategy);
108 }
109
110 this.popupMenuStrategies.add(itemRadioStrategy);
111 itemRadioStrategy.setToolTipText(
112 I18nUtil.valueByKey(String.format(PanelTrailingAddress.I18N_TOOLTIP_STRATEGY, nameStrategy))
113 );
114 itemRadioStrategy.setEnabled(false);
115 }
116
117 this.labelEngine.setText(MediatorHelper.model().getMediatorEngine().getAuto().toString());
118 this.labelEngine.setName(PanelTrailingAddress.MENU_VENDOR);
119 this.popupMenuEngines.setLayout(UiUtil.getColumnLayout(MediatorHelper.model().getMediatorEngine().getEngines().size()));
120 var groupEngine = new ButtonGroup();
121 for (final Engine engine : MediatorHelper.model().getMediatorEngine().getEngines()) {
122 JMenuItem itemRadioEngine = new JRadioButtonMenuItem(engine.toString(), engine == MediatorHelper.model().getMediatorEngine().getAuto());
123 itemRadioEngine.setName(PanelTrailingAddress.ITEM_RADIO_VENDOR + engine);
124 itemRadioEngine.addActionListener(actionEvent -> {
125 this.labelEngine.setText(engine.toString());
126 MediatorHelper.model().getMediatorEngine().setEngineByUser(engine);
127 });
128 this.popupMenuEngines.add(itemRadioEngine);
129 groupEngine.add(itemRadioEngine);
130 }
131
132 this.loader = new JProgressBar();
133 var dimension = UIManager.getDimension("ProgressBar.horizontalSize");
134 this.loader.setPreferredSize(new Dimension(32, dimension.height));
135 this.loader.setIndeterminate(true);
136 this.add(this.loader);
137
138 this.labelEngine.addMouseListener(new MouseAdapter() {
139 @Override
140 public void mousePressed(MouseEvent e) {
141 Arrays.stream(PanelTrailingAddress.this.popupMenuEngines.getComponents())
142 .map(JComponent.class::cast)
143 .forEach(JComponent::updateUI);
144 PanelTrailingAddress.this.popupMenuEngines.updateUI();
145 SwingUtilities.invokeLater(() -> {
146 PanelTrailingAddress.this.popupMenuEngines.show(e.getComponent(), e.getComponent().getX(),5 + e.getComponent().getY() + e.getComponent().getHeight());
147 PanelTrailingAddress.this.popupMenuEngines.setLocation(e.getComponent().getLocationOnScreen().x,5 + e.getComponent().getLocationOnScreen().y + e.getComponent().getHeight());
148 });
149 }
150 });
151 this.labelStrategy.addMouseListener(new MouseAdapter() {
152 @Override
153 public void mousePressed(MouseEvent e) {
154 Arrays.stream(PanelTrailingAddress.this.popupMenuStrategies.getComponents())
155 .map(JComponent.class::cast)
156 .forEach(JComponent::updateUI);
157 for (var i = 0 ; i < PanelTrailingAddress.this.getMenuError().getItemCount() ; i++) {
158 PanelTrailingAddress.this.getMenuError().getItem(i).updateUI();
159 }
160 PanelTrailingAddress.this.popupMenuStrategies.updateUI();
161 SwingUtilities.invokeLater(() -> {
162 PanelTrailingAddress.this.popupMenuStrategies.show(e.getComponent(), e.getComponent().getX(),5 + e.getComponent().getY() + e.getComponent().getHeight());
163 PanelTrailingAddress.this.popupMenuStrategies.setLocation(e.getComponent().getLocationOnScreen().x,5 + e.getComponent().getLocationOnScreen().y + e.getComponent().getHeight());
164 });
165 }
166 });
167
168 this.labelTarget.setText(PanelTrailingAddress.PARAM_AUTO);
169 this.labelTarget.addMouseListener(new TargetMouseAdapter(panelAddressBar));
170
171 this.add(this.labelTarget);
172 this.add(this.labelEngine);
173 this.add(this.labelStrategy);
174 this.add(this.buttonStart);
175 this.setCursor(Cursor.getDefaultCursor());
176 this.loader.setVisible(false);
177 }
178
179 public void endPreparation() {
180 this.buttonStart.setToolTipText(I18nUtil.valueByKey("BUTTON_START_TOOLTIP"));
181 this.buttonStart.setInjectionReady();
182 this.loader.setVisible(false);
183 }
184
185 public void reset() {
186 this.labelStrategy.setText("Strategy auto");
187 if (MediatorHelper.model().getMediatorEngine().getEngineByUser() == MediatorHelper.model().getMediatorEngine().getAuto()) {
188 this.labelEngine.setText(MediatorHelper.model().getMediatorEngine().getAuto().toString());
189 }
190 Arrays.stream(this.popupMenuStrategies.getComponents())
191 .forEach(component -> component.setEnabled(false));
192 this.getMenuError().removeAll();
193
194 this.groupStrategy.clearSelection();
195 Iterable<AbstractButton> iterable = () -> this.groupStrategy.getElements().asIterator();
196 StreamSupport.stream(iterable.spliterator(), false)
197 .filter(abstractButton -> abstractButton.getName().startsWith(PanelTrailingAddress.PREFIX_NAME_ERROR))
198 .forEach(this.groupStrategy::remove);
199 }
200
201 public void setEngine(Engine engine) {
202 this.labelEngine.setText(engine.toString());
203 this.itemRadioStrategyError.removeAll();
204 var indexError = 0;
205 if (
206 engine != MediatorHelper.model().getMediatorEngine().getAuto()
207 && engine.instance().getModelYaml().getStrategy().getError() != null
208 ) {
209 for (Method methodError: engine.instance().getModelYaml().getStrategy().getError().getMethod()) {
210 JMenuItem itemRadioError = new JRadioButtonMenuItem(methodError.getName());
211 itemRadioError.setEnabled(false);
212 itemRadioError.setName(PanelTrailingAddress.PREFIX_NAME_ERROR + methodError.getName());
213 this.itemRadioStrategyError.add(itemRadioError);
214 this.groupStrategy.add(itemRadioError);
215 int indexErrorFinal = indexError;
216 itemRadioError.addActionListener(actionEvent -> {
217 this.labelStrategy.setText(methodError.getName());
218 MediatorHelper.model().getMediatorStrategy().setStrategy(MediatorHelper.model().getMediatorStrategy().getError());
219 MediatorHelper.model().getMediatorStrategy().getError().setIndexErrorStrategy(indexErrorFinal);
220 });
221 indexError++;
222 }
223 }
224 }
225
226 public void activateStrategy(AbstractStrategy strategy) {
227 if (strategy instanceof StrategyError strategyError) {
228 this.labelStrategy.setText(strategyError.toString());
229 int indexError = strategyError.getIndexErrorStrategy();
230 String nameError = MediatorHelper.model().getMediatorEngine().getEngine().instance().getModelYaml().getStrategy().getError().getMethod().get(
231 indexError
232 ).getName();
233
234 Arrays.stream(this.getMenuError().getMenuComponents())
235 .map(JRadioButtonMenuItem.class::cast)
236 .filter(component -> component.getText().equals(nameError))
237 .forEach(jRadioButtonMenuItem -> {
238 jRadioButtonMenuItem.setSelected(true);
239 this.labelStrategy.setText(nameError);
240 });
241 } else {
242 this.labelStrategy.setText(strategy.toString());
243 Arrays.stream(this.popupMenuStrategies.getComponents())
244 .map(JMenuItem.class::cast)
245 .filter(jMenuItem -> jMenuItem.getText().equals(strategy.toString()))
246 .forEach(jMenuItem -> jMenuItem.setSelected(true));
247 }
248 }
249
250 public void markInvulnerable(AbstractStrategy strategy) {
251 Arrays.stream(this.popupMenuStrategies.getComponents())
252 .map(JMenuItem.class::cast)
253 .filter(jMenuItem -> jMenuItem.getText().equals(strategy.toString()))
254 .forEach(jMenuItem -> jMenuItem.setEnabled(false));
255 }
256
257 public void markInvulnerable(int indexMethodError, AbstractStrategy strategy) {
258 Arrays.stream(this.popupMenuStrategies.getSubElements())
259 .map(JMenuItem.class::cast)
260 .filter(jMenuItem -> jMenuItem.getText().equals(strategy.toString()))
261 .map(JMenu.class::cast)
262 .filter(jMenuItem -> {
263 var isNotNull = true;
264
265
266
267 try {
268 isNotNull = jMenuItem.getItem(indexMethodError) != null;
269 } catch (ArrayIndexOutOfBoundsException e) {
270 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
271 return false;
272 }
273 return isNotNull;
274 })
275 .forEach(jMenuItem -> jMenuItem.getItem(indexMethodError).setEnabled(false));
276 }
277
278 private JMenu getMenuError() {
279 var nameError = MediatorHelper.model().getMediatorStrategy().getError().getName();
280 return (JMenu) Arrays.stream(this.popupMenuStrategies.getComponents())
281 .map(JMenuItem.class::cast)
282 .filter(jMenuItem -> jMenuItem.getText().equalsIgnoreCase(nameError))
283 .findFirst()
284 .orElse(new JMenuItem("Mock"));
285 }
286
287 public void markVulnerable(AbstractStrategy strategy) {
288 Arrays.stream(this.popupMenuStrategies.getComponents())
289 .map(JMenuItem.class::cast)
290 .filter(jMenuItem -> jMenuItem.getText().equals(strategy.toString()))
291 .forEach(jMenuItem -> jMenuItem.setEnabled(true));
292 }
293
294 public void markVulnerable(int indexMethodError, AbstractStrategy strategy) {
295
296 try {
297 Arrays.stream(this.popupMenuStrategies.getComponents())
298 .map(JMenuItem.class::cast)
299 .filter(jMenuItem -> jMenuItem.getText().equals(strategy.toString()))
300 .map(JMenu.class::cast)
301 .filter(jMenuItem -> jMenuItem.getItem(indexMethodError) != null)
302 .forEach(jMenuItem -> {
303 jMenuItem.setEnabled(true);
304 jMenuItem.getItem(indexMethodError).setEnabled(true);
305 });
306 } catch (ArrayIndexOutOfBoundsException e) {
307 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
308 }
309 }
310
311 private class TargetMouseAdapter extends MouseAdapter {
312
313 private final PanelAddressBar panelAddressBar;
314
315 public TargetMouseAdapter(PanelAddressBar panelAddressBar) {
316 this.panelAddressBar = panelAddressBar;
317 }
318
319 @Override
320 public void mousePressed(MouseEvent event) {
321 PanelTrailingAddress.this.popupMenuTargets.removeAll();
322 JRadioButtonMenuItem menuParamAuto = new JRadioButtonMenuItem(PanelTrailingAddress.PARAM_AUTO);
323 menuParamAuto.setActionCommand(PanelTrailingAddress.PARAM_AUTO);
324 menuParamAuto.addActionListener(actionEvent ->
325 PanelTrailingAddress.this.labelTarget.setText(menuParamAuto.getText())
326 );
327 PanelTrailingAddress.this.popupMenuTargets.add(menuParamAuto);
328
329 var rawQuery = this.panelAddressBar.getTextFieldAddress().getText().trim();
330 var rawRequest = this.panelAddressBar.getTextFieldRequest().getText().trim();
331 var rawHeader = this.panelAddressBar.getTextFieldHeader().getText().trim();
332
333 var selection = PanelTrailingAddress.this.groupRadio.getSelection();
334 String selectionCommand;
335 if (selection != null) {
336 selectionCommand = selection.getActionCommand();
337 } else {
338 selectionCommand = StringUtils.EMPTY;
339 }
340 PanelTrailingAddress.this.groupRadio = new ButtonGroup();
341 PanelTrailingAddress.this.groupRadio.add(menuParamAuto);
342 JMenu menuQuery = new JMenu("Query");
343 if (!rawQuery.isEmpty()) {
344 try {
345 rawQuery = !rawQuery.matches("(?i)^\\w+://.*") ? "http://"+ rawQuery : rawQuery;
346 var url = new URI(rawQuery).toURL();
347 if (url.getQuery() != null) {
348 this.buildMenu(url.getQuery(), ParameterUtil.PREFIX_COMMAND_QUERY, selectionCommand, menuQuery);
349 }
350 } catch (IllegalArgumentException | MalformedURLException | URISyntaxException e) {
351 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Incorrect URL: {}", e.getMessage());
352 return;
353 }
354 }
355
356 JMenu menuRequest = new JMenu("Request");
357 if (!rawRequest.isEmpty()) {
358 this.buildMenu(rawRequest, ParameterUtil.PREFIX_COMMAND_REQUEST, selectionCommand, menuRequest);
359 }
360
361 JMenu menuHeader = new JMenu("Header");
362 if (!rawHeader.isEmpty()) {
363 this.buildMenuHeader(rawHeader, selectionCommand, menuHeader);
364 }
365
366 Arrays.stream(PanelTrailingAddress.this.popupMenuTargets.getComponents())
367 .map(JComponent.class::cast)
368 .forEach(c -> c.setEnabled(false));
369 menuParamAuto.setEnabled(true);
370 if (PanelTrailingAddress.this.groupRadio.getSelection() == null) {
371 menuParamAuto.setSelected(true);
372 PanelTrailingAddress.this.labelTarget.setText(menuParamAuto.getText());
373 }
374 menuQuery.setEnabled(menuQuery.getMenuComponentCount() > 0);
375 menuRequest.setEnabled(menuRequest.getMenuComponentCount() > 0);
376 menuHeader.setEnabled(menuHeader.getMenuComponentCount() > 0);
377
378 if (
379 menuQuery.getMenuComponentCount() > 0
380 || menuRequest.getMenuComponentCount() > 0
381 || menuHeader.getMenuComponentCount() > 0
382 ) {
383 Arrays.stream(PanelTrailingAddress.this.popupMenuTargets.getComponents())
384 .map(JComponent.class::cast)
385 .forEach(JComponent::updateUI);
386 PanelTrailingAddress.this.popupMenuTargets.updateUI();
387 SwingUtilities.invokeLater(() -> {
388 PanelTrailingAddress.this.popupMenuTargets.show(event.getComponent(), event.getComponent().getX(), 5 + event.getComponent().getY() + event.getComponent().getHeight());
389 PanelTrailingAddress.this.popupMenuTargets.setLocation(event.getComponent().getLocationOnScreen().x, 5 + event.getComponent().getLocationOnScreen().y + event.getComponent().getHeight());
390 });
391 } else {
392 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, "Missing parameter to inject");
393 }
394 }
395
396 private void buildMenuHeader(String rawHeader, String selectionCommand, JMenu menuHeader) {
397 var listHeaders = Pattern.compile("\\\\r\\\\n")
398 .splitAsStream(rawHeader)
399 .map(keyValue -> Arrays.copyOf(keyValue.split(":"), 2))
400 .map(keyValue -> new AbstractMap.SimpleEntry<>(
401 keyValue[0],
402 keyValue[1] == null ? StringUtils.EMPTY : keyValue[1]
403 ))
404 .toList();
405 listHeaders.forEach(entry -> {
406 JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(entry.getKey());
407 menuItem.setSelected((ParameterUtil.PREFIX_COMMAND_HEADER + entry.getKey()).equals(selectionCommand));
408 menuItem.setActionCommand(ParameterUtil.PREFIX_COMMAND_HEADER + entry.getKey());
409 menuItem.addActionListener(actionEvent ->
410 PanelTrailingAddress.this.labelTarget.setText(entry.getKey())
411 );
412 groupRadio.add(menuItem);
413 menuHeader.add(menuItem);
414 });
415 if (listHeaders.stream().anyMatch(s -> CookiesUtil.COOKIE.equalsIgnoreCase(s.getKey()))) {
416 var cookies = listHeaders.stream()
417 .filter(s -> CookiesUtil.COOKIE.equalsIgnoreCase(s.getKey()))
418 .findFirst()
419 .orElse(new AbstractMap.SimpleEntry<>(CookiesUtil.COOKIE, ""));
420 if (!cookies.getValue().trim().isEmpty()) {
421 JMenu menuCookie = new JMenu(CookiesUtil.COOKIE);
422 String[] cookieValues = StringUtils.split(cookies.getValue(), ";");
423 Stream.of(cookieValues).forEach(cookie -> {
424 String[] cookieEntry = StringUtils.split(cookie, "=");
425 JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(cookieEntry[0].trim());
426 menuItem.setSelected((ParameterUtil.PREFIX_COMMAND_COOKIE + cookieEntry[0].trim()).equals(selectionCommand));
427 menuItem.setActionCommand(ParameterUtil.PREFIX_COMMAND_COOKIE + cookieEntry[0].trim());
428 menuItem.addActionListener(actionEvent ->
429 PanelTrailingAddress.this.labelTarget.setText(cookieEntry[0].trim())
430 );
431 groupRadio.add(menuItem);
432 menuCookie.add(menuItem);
433 });
434 menuHeader.addSeparator();
435 menuHeader.add(menuCookie);
436 }
437 }
438 PanelTrailingAddress.this.popupMenuTargets.add(menuHeader);
439 }
440
441 private void buildMenu(String rawParams, String prefixCommand, String selectionCommand, JMenu menu) {
442 Pattern.compile("&").splitAsStream(rawParams)
443 .map(keyValue -> Arrays.copyOf(keyValue.split("="), 2))
444 .map(keyValue -> new AbstractMap.SimpleEntry<>(
445 keyValue[0],
446 keyValue[1] == null ? StringUtils.EMPTY : keyValue[1]
447 ))
448 .forEach(entry -> {
449 JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(entry.getKey());
450 menuItem.setSelected((prefixCommand + entry.getKey()).equals(selectionCommand));
451 menuItem.setActionCommand(prefixCommand + entry.getKey());
452 menuItem.addActionListener(actionEvent ->
453 PanelTrailingAddress.this.labelTarget.setText(entry.getKey())
454 );
455 PanelTrailingAddress.this.groupRadio.add(menuItem);
456 menu.add(menuItem);
457 });
458 PanelTrailingAddress.this.popupMenuTargets.add(menu);
459 }
460 }
461
462
463
464
465 public JComponent getLoader() {
466 return this.loader;
467 }
468
469 public ButtonStart getButtonStart() {
470 return this.buttonStart;
471 }
472
473 public ButtonGroup getGroupRadio() {
474 return this.groupRadio;
475 }
476 }