Skip to content

Commit

Permalink
Feat/flavor form urllib (#403)
Browse files Browse the repository at this point in the history
* Use URLLIB. Prepare to parse generator as well.

The latter uses global variables to store the state.
The idea is that we can be invoked either way, parsing
a flavor name (and generating a spec and a pretty description)
or parsing the specs (and generating the name from it).

* Avoid script injection.

* Avoid any HTML tags in flavor name.

* Appease flake8

Signed-off-by: Kurt Garloff <[email protected]>
  • Loading branch information
garloff authored Dec 6, 2023
1 parent ec222a8 commit 14635d1
Showing 1 changed file with 43 additions and 27 deletions.
70 changes: 43 additions & 27 deletions Tests/iaas/flavor-naming/flavor-form.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,55 @@
or a human-readable description of the flavor.
"""

# import os
import os
import sys
import re
# import traceback
# TODO: Replace cgi by urllib, cgi is deprecated
import cgi
import urllib.parse
import importlib
fnmck = importlib.import_module("flavor-name-check")

# Global variables
FLAVOR_NAME = ""
FLAVOR_SPEC = ()
ERROR = ""

class TestForm:
"Class for testing via cmd line"
def __init__(self, fnm):
self.value = fnm

def parse_name(fnm):
"return tuple with flavor description"
global FLAVOR_SPEC, FLAVOR_NAME, ERROR
# Sanitize
# fnm = re.sub(r"<( *script)", r"<!--\1", fnm, flags=re.I)
fnm = re.sub(r"<", r"&lt;", fnm)
fnm = re.sub(r">", r"&gt;", fnm)
FLAVOR_NAME = fnm
try:
FLAVOR_SPEC = fnmck.parsename(fnm)
except (TypeError, NameError, KeyError) as exc:
ERROR = f"\tERROR<br/>\n\t{exc}"
return ()
ERROR = ""
return FLAVOR_SPEC


def parse_form(form):
def output_parse():
"output pretty description from SCS flavor name"
import importlib
fnmd = importlib.import_module("flavor-name-describe")
fnm = ""
try:
fnm = form["flavor"].value
except KeyError:
pass
print('\t<br/>\n\t<FORM ACTION="/cgi-bin/flavor-form.py" METHOD="GET">')
print(f'\t Flavor name: <INPUT TYPE="text" NAME="flavor" SIZE=24 VALUE="{fnm}"/>')
print(f'\t Flavor name: <INPUT TYPE="text" NAME="flavor" SIZE=24 VALUE="{FLAVOR_NAME}"/>')
print('\t <INPUT TYPE="submit" VALUE="Submit"/>')
# print(' <INPUT TYPE="reset" VALUE="Clear"/>\n</FORM>')
print('\t</FORM>')
if fnm:
print("\t<br/><b>Flavor</b>")
try:
fnmd.main((fnm,))
except (TypeError, NameError, KeyError) as exc:
print(f"\tERROR<br/>\n\t{exc}")
if FLAVOR_NAME:
print(f"\t<br/><b>Flavor {FLAVOR_NAME}:</b>")
if FLAVOR_SPEC:
print(f"\t{fnmd.prettyname(FLAVOR_SPEC)}")
else:
print("\tNot an SCS flavor")
if ERROR:
print(f"\t<br/>{ERROR})")


def parse_generate(form):
def output_generate():
"input details to generate SCS flavor name"
print("\tNot implemented yet as webform, use")
print('\t<tt><a href="https://github.com/SovereignCloudStack/standards/blob/main/Tests/iaas/flavor-naming/flavor-name-check.py">flavor-name-check.py</a> -i</tt>')
Expand All @@ -57,19 +69,23 @@ def parse_generate(form):
def main(argv):
"Entry point for cgi flavor parsing"
print("Content-Type: text/html\n")
form = cgi.FieldStorage()
form = {"flavor": [""]}
if 'QUERY_STRING' in os.environ:
form = urllib.parse.parse_qs(os.environ['QUERY_STRING'])
# For testing
if len(argv) > 0:
form = {"flavor": TestForm(argv[0])}
form = {"flavor": [argv[0],]}
find_parse = re.compile(r'^[ \t]*<!\-\-FLAVOR\-FORM: PARSE\-\->[ \t]*$')
find_generate = re.compile(r'^[ \t]*<!\-\-FLAVOR\-FORM: GENERATE\-\->[ \t]*$')
if "flavor" in form:
parse_name(form["flavor"][0])
with open("page/index.html", "r", encoding='utf-8') as infile:
for line in infile:
print(line, end='')
if find_parse.match(line):
parse_form(form)
output_parse()
elif find_generate.match(line):
parse_generate(form)
output_generate()


if __name__ == "__main__":
Expand Down

0 comments on commit 14635d1

Please sign in to comment.