pywebexec 1.8.4__tar.gz → 1.9.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. {pywebexec-1.8.4/pywebexec.egg-info → pywebexec-1.9.1}/PKG-INFO +2 -1
  2. {pywebexec-1.8.4 → pywebexec-1.9.1}/pyproject.toml +1 -0
  3. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/pywebexec.py +36 -4
  4. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/css/style.css +8 -1
  5. pywebexec-1.9.1/pywebexec/swagger.yaml +54 -0
  6. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/templates/index.html +1 -1
  7. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/version.py +2 -2
  8. {pywebexec-1.8.4 → pywebexec-1.9.1/pywebexec.egg-info}/PKG-INFO +2 -1
  9. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec.egg-info/SOURCES.txt +1 -0
  10. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec.egg-info/requires.txt +1 -0
  11. {pywebexec-1.8.4 → pywebexec-1.9.1}/.github/workflows/python-publish.yml +0 -0
  12. {pywebexec-1.8.4 → pywebexec-1.9.1}/.gitignore +0 -0
  13. {pywebexec-1.8.4 → pywebexec-1.9.1}/LICENSE +0 -0
  14. {pywebexec-1.8.4 → pywebexec-1.9.1}/README.md +0 -0
  15. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/__init__.py +0 -0
  16. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/host_ip.py +0 -0
  17. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/css/xterm.css +0 -0
  18. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/fonts/CommitMonoNerdFontMono-Regular.ttf +0 -0
  19. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/fonts/LICENSE +0 -0
  20. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/aborted.svg +0 -0
  21. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/copy.svg +0 -0
  22. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/copy_ok.svg +0 -0
  23. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/down-arrow.svg +0 -0
  24. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/failed.svg +0 -0
  25. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/favicon.svg +0 -0
  26. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/fit-tty.svg +0 -0
  27. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/fit-win.svg +0 -0
  28. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/font-decrease.svg +0 -0
  29. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/font-increase.svg +0 -0
  30. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/norun.svg +0 -0
  31. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/pause.svg +0 -0
  32. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/popup.svg +0 -0
  33. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/resume.svg +0 -0
  34. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/running.svg +0 -0
  35. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/images/success.svg +0 -0
  36. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/commands.js +0 -0
  37. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/popup.js +0 -0
  38. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/script.js +0 -0
  39. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/LICENSE +0 -0
  40. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/addon-canvas.js +0 -0
  41. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/addon-canvas.js.map +0 -0
  42. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/addon-fit.js +0 -0
  43. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/addon-fit.js.map +0 -0
  44. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/addon-unicode-graphemes.js +0 -0
  45. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/addon-unicode-graphemes.js.map +0 -0
  46. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/addon-unicode11.js +0 -0
  47. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/addon-unicode11.js.map +0 -0
  48. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/xterm.js +0 -0
  49. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/static/js/xterm/xterm.js.map +0 -0
  50. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/templates/__init__.py +0 -0
  51. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec/templates/popup.html +0 -0
  52. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec.egg-info/dependency_links.txt +0 -0
  53. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec.egg-info/entry_points.txt +0 -0
  54. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexec.egg-info/top_level.txt +0 -0
  55. {pywebexec-1.8.4 → pywebexec-1.9.1}/pywebexecdev +0 -0
  56. {pywebexec-1.8.4 → pywebexec-1.9.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.8.4
3
+ Version: 1.9.1
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -56,6 +56,7 @@ Requires-Dist: python-daemon>=2.3.2
56
56
  Requires-Dist: cryptography>=40.0.2
57
57
  Requires-Dist: Flask>=2.0.3
58
58
  Requires-Dist: Flask-HTTPAuth>=4.8.0
59
+ Requires-Dist: flask-swagger-ui>=4.11.1
59
60
  Requires-Dist: pexpect>=4.9.0
60
61
  Requires-Dist: gunicorn>=21.2.0
61
62
  Requires-Dist: ldap3>=2.9.1
@@ -13,6 +13,7 @@ dependencies = [
13
13
  "cryptography>=40.0.2",
14
14
  "Flask>=2.0.3",
15
15
  "Flask-HTTPAuth>=4.8.0",
16
+ "flask-swagger-ui>=4.11.1",
16
17
  "pexpect>=4.9.0",
17
18
  "gunicorn>=21.2.0",
18
19
  "ldap3>=2.9.1",
@@ -28,6 +28,8 @@ import logging
28
28
  from pathlib import Path
29
29
  import pyte
30
30
  from . import host_ip
31
+ from flask_swagger_ui import get_swaggerui_blueprint # new import
32
+ import yaml # new import
31
33
 
32
34
  if os.environ.get('PYWEBEXEC_LDAP_SERVER'):
33
35
  from ldap3 import Server, Connection, ALL, SIMPLE, SUBTREE, Tls
@@ -35,7 +37,6 @@ if os.environ.get('PYWEBEXEC_LDAP_SERVER'):
35
37
  app = Flask(__name__)
36
38
  app.secret_key = os.urandom(24) # Secret key for session management
37
39
  app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' # Add SameSite attribute to session cookies
38
- app.config['SESSION_COOKIE_SECURE'] = True
39
40
  app.config['SESSION_COOKIE_HTTPONLY'] = True
40
41
  auth = HTTPBasicAuth()
41
42
 
@@ -46,6 +47,7 @@ app.config['LDAP_BASE_DN'] = os.environ.get('PYWEBEXEC_LDAP_BASE_DN')
46
47
  app.config['LDAP_BIND_DN'] = os.environ.get('PYWEBEXEC_LDAP_BIND_DN')
47
48
  app.config['LDAP_BIND_PASSWORD'] = os.environ.get('PYWEBEXEC_LDAP_BIND_PASSWORD')
48
49
 
50
+
49
51
  # Get the Gunicorn error logger
50
52
  gunicorn_logger = logging.getLogger('gunicorn.error')
51
53
  app.logger.handlers = gunicorn_logger.handlers
@@ -590,7 +592,23 @@ def check_processes():
590
592
  'exit_code': -1,
591
593
  })
592
594
 
593
- parseargs()
595
+ args = parseargs()
596
+ if args.cert:
597
+ app.config['SESSION_COOKIE_SECURE'] = True
598
+ app.config['TITLE'] = f"{args.title} API"
599
+
600
+ # Register Swagger UI blueprint with safe token included in API_URL
601
+ SWAGGER_URL = '/v0/documentation'
602
+ API_URL = '/swagger.yaml'
603
+ swaggerui_blueprint = get_swaggerui_blueprint(
604
+ SWAGGER_URL,
605
+ API_URL,
606
+ config={
607
+ 'app_name': f"{args.title} API",
608
+ 'layout': 'BaseLayout'
609
+ }
610
+ )
611
+ app.register_blueprint(swaggerui_blueprint, url_prefix=SWAGGER_URL)
594
612
 
595
613
  def log_info(fromip, user, message):
596
614
  app.logger.info(f"{user} {fromip}: {message}")
@@ -625,10 +643,10 @@ def stop_command(command_id):
625
643
 
626
644
  @app.before_request
627
645
  def check_authentication():
628
- # Check for token in URL if TOKEN_URL is set
629
646
  token = app.config.get('TOKEN_URL')
630
647
  if token and request.endpoint not in ['login', 'static']:
631
- if request.args.get('token') == token:
648
+ if request.args.get('token') == token or session.get('token') == token:
649
+ session['token'] = token
632
650
  return
633
651
  return jsonify({'error': 'Forbidden'}), 403
634
652
 
@@ -830,6 +848,20 @@ def do_popup(command_id):
830
848
  </html>
831
849
  """
832
850
 
851
+ @app.route('/swagger.yaml')
852
+ def swagger_yaml():
853
+ swagger_path = os.path.join(os.path.dirname(__file__), 'swagger.yaml')
854
+ try:
855
+ with open(swagger_path, 'r') as f:
856
+ swagger_spec_str = f.read()
857
+ swagger_spec = yaml.safe_load(swagger_spec_str)
858
+ # Set title dynamically using the app configuration
859
+ swagger_spec['info']['title'] = app.config.get('TITLE', 'PyWebExec API')
860
+ swagger_spec_str = yaml.dump(swagger_spec)
861
+ return Response(swagger_spec_str, mimetype='application/yaml')
862
+ except Exception as e:
863
+ return Response(f"Error reading swagger spec: {e}", status=500)
864
+
833
865
  def main():
834
866
  global COMMAND_STATUS_DIR
835
867
  basef = f"{CONFDIR}/pywebexec_{args.listen}:{args.port}"
@@ -91,10 +91,13 @@ form {
91
91
  vertical-align: middle;
92
92
  }
93
93
  .title-icon {
94
- width: 30px;
94
+ display: inline;
95
95
  height: 30px;
96
96
  background-image: url("/static/images/favicon.svg");
97
+ background-size: 30px 30px;
98
+ background-repeat: no-repeat;
97
99
  vertical-align: bottom;
100
+ padding-left: 35px;
98
101
  }
99
102
  #thStatus {
100
103
  cursor: pointer;
@@ -383,4 +386,8 @@ span {
383
386
 
384
387
  .xterm-accessibility {
385
388
  display: none;
389
+ }
390
+ .swaggerlink {
391
+ text-decoration: none;
392
+ font-size: 10px;
386
393
  }
@@ -0,0 +1,54 @@
1
+ swagger: "2.0"
2
+ info:
3
+ title: PyWebExec API
4
+ version: "1.0"
5
+ paths:
6
+ /run_command:
7
+ post:
8
+ summary: "Run a command"
9
+ consumes:
10
+ - application/json
11
+ produces:
12
+ - application/json
13
+ parameters:
14
+ - in: body
15
+ name: commandRequest
16
+ schema:
17
+ type: object
18
+ properties:
19
+ command:
20
+ type: string
21
+ params:
22
+ type: array
23
+ items:
24
+ type: string
25
+ rows:
26
+ type: integer
27
+ cols:
28
+ type: integer
29
+ responses:
30
+ "200":
31
+ description: "Command started"
32
+ /command_status/{command_id}:
33
+ get:
34
+ summary: "Get command status"
35
+ parameters:
36
+ - in: path
37
+ name: command_id
38
+ required: true
39
+ type: string
40
+ responses:
41
+ "200":
42
+ description: "Command status returned"
43
+ /commands:
44
+ get:
45
+ summary: "List commands"
46
+ responses:
47
+ "200":
48
+ description: "List of all commands"
49
+ /executables:
50
+ get:
51
+ summary: "List executables"
52
+ responses:
53
+ "200":
54
+ description: "List of executables returned as an array of executable names"
@@ -11,7 +11,7 @@
11
11
  <div id="dimmer" class="dimmer">
12
12
  <div class="dimmer-text">Server not available</div>
13
13
  </div>
14
- <h2><span class="status-icon title-icon"></span>{{ title }}</h2>
14
+ <h2><span class="status-icon title-icon">{{ title }}&nbsp;<a class="swaggerlink" href="/v0/documentation" target="_blank">swagger</a></span></h2>
15
15
  <form id="launchForm" class="form-inline">
16
16
  <label for="command">Command</label>
17
17
  <div class="input-group">
@@ -17,5 +17,5 @@ __version__: str
17
17
  __version_tuple__: VERSION_TUPLE
18
18
  version_tuple: VERSION_TUPLE
19
19
 
20
- __version__ = version = '1.8.4'
21
- __version_tuple__ = version_tuple = (1, 8, 4)
20
+ __version__ = version = '1.9.1'
21
+ __version_tuple__ = version_tuple = (1, 9, 1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: pywebexec
3
- Version: 1.8.4
3
+ Version: 1.9.1
4
4
  Summary: Simple Python HTTP Exec Server
5
5
  Home-page: https://github.com/joknarf/pywebexec
6
6
  Author: Franck Jouvanceau
@@ -56,6 +56,7 @@ Requires-Dist: python-daemon>=2.3.2
56
56
  Requires-Dist: cryptography>=40.0.2
57
57
  Requires-Dist: Flask>=2.0.3
58
58
  Requires-Dist: Flask-HTTPAuth>=4.8.0
59
+ Requires-Dist: flask-swagger-ui>=4.11.1
59
60
  Requires-Dist: pexpect>=4.9.0
60
61
  Requires-Dist: gunicorn>=21.2.0
61
62
  Requires-Dist: ldap3>=2.9.1
@@ -8,6 +8,7 @@ setup.cfg
8
8
  pywebexec/__init__.py
9
9
  pywebexec/host_ip.py
10
10
  pywebexec/pywebexec.py
11
+ pywebexec/swagger.yaml
11
12
  pywebexec/version.py
12
13
  pywebexec.egg-info/PKG-INFO
13
14
  pywebexec.egg-info/SOURCES.txt
@@ -2,6 +2,7 @@ python-daemon>=2.3.2
2
2
  cryptography>=40.0.2
3
3
  Flask>=2.0.3
4
4
  Flask-HTTPAuth>=4.8.0
5
+ flask-swagger-ui>=4.11.1
5
6
  pexpect>=4.9.0
6
7
  gunicorn>=21.2.0
7
8
  ldap3>=2.9.1
File without changes
File without changes
File without changes
File without changes
File without changes