| tierno | d125caf | 2018-11-22 16:05:54 +0000 | [diff] [blame] | 1 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 2 | # you may not use this file except in compliance with the License. |
| 3 | # You may obtain a copy of the License at |
| 4 | # |
| 5 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 6 | # |
| 7 | # Unless required by applicable law or agreed to in writing, software |
| 8 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 9 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
| 10 | # implied. |
| 11 | # See the License for the specific language governing permissions and |
| 12 | # limitations under the License. |
| 13 | |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 14 | """ |
| 15 | Contains html text in variables to make and html response |
| 16 | """ |
| 17 | |
| 18 | import yaml |
| 19 | from http import HTTPStatus |
| tierno | ef4e224 | 2018-10-31 17:09:52 +0100 | [diff] [blame] | 20 | from html import escape as html_escape |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 21 | |
| 22 | __author__ = "Alfonso Tierno <alfonso.tiernosepulveda@telefonica.com>" |
| 23 | |
| 24 | html_start = """ |
| 25 | <!DOCTYPE html> |
| 26 | <html> |
| 27 | <head> |
| 28 | <link href="/osm/static/style.css" rel="stylesheet"> |
| K Sai Kiran | 8748af5 | 2020-06-25 16:23:32 +0530 | [diff] [blame] | 29 | <title>Welcome to OSM</title> |
| 30 | <link rel="shortcut icon" href="/osm/static/favicon.ico"> |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 31 | </head> |
| 32 | <body> |
| 33 | <div id="osm_topmenu"> |
| 34 | <div> |
| tierno | 2236d20 | 2018-05-16 19:05:16 +0200 | [diff] [blame] | 35 | <a href="https://osm.etsi.org"> <img src="/osm/static/OSM-logo.png" height="42" width="100" |
| 36 | style="vertical-align:middle"> </a> |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 37 | <a>( {} )</a> |
| tierno | 36ec860 | 2018-11-02 17:27:11 +0100 | [diff] [blame] | 38 | <a href="/osm/pdu/v1/pdu_descriptors">PDUs </a> |
| tierno | b24258a | 2018-10-04 18:39:49 +0200 | [diff] [blame] | 39 | <a href="/osm/vnfpkgm/v1/vnf_packages">VNFDs </a> |
| 40 | <a href="/osm/nsd/v1/ns_descriptors">NSDs </a> |
| 41 | <a href="/osm/nslcm/v1/ns_instances">NSs </a> |
| Felipe Vicens | b57758d | 2018-10-16 16:00:20 +0200 | [diff] [blame] | 42 | <a href="/osm/nst/v1/netslice_templates">NSTDs </a> |
| Felipe Vicens | 07f3172 | 2018-10-29 15:16:44 +0100 | [diff] [blame] | 43 | <a href="/osm/nsilcm/v1/netslice_instances">NSIs </a> |
| tierno | f27c79b | 2018-03-12 17:08:42 +0100 | [diff] [blame] | 44 | <a href="/osm/admin/v1/users">USERs </a> |
| 45 | <a href="/osm/admin/v1/projects">PROJECTs </a> |
| 46 | <a href="/osm/admin/v1/tokens">TOKENs </a> |
| tierno | f759d82 | 2018-06-11 18:54:54 +0200 | [diff] [blame] | 47 | <a href="/osm/admin/v1/vim_accounts">VIMs </a> |
| tierno | 55ba2e6 | 2018-12-11 17:22:22 +0000 | [diff] [blame] | 48 | <a href="/osm/admin/v1/wim_accounts">WIMs </a> |
| tierno | f759d82 | 2018-06-11 18:54:54 +0200 | [diff] [blame] | 49 | <a href="/osm/admin/v1/sdns">SDNs </a> |
| tierno | 7fd2487 | 2019-12-10 10:57:17 +0000 | [diff] [blame] | 50 | <a href="/osm/admin/v1/k8sclusters">K8s_clusters </a> |
| tierno | c67b0e9 | 2019-11-05 12:45:29 +0000 | [diff] [blame] | 51 | <a href="/osm/admin/v1/k8srepos">K8s_repos </a> |
| K Sai Kiran | 8748af5 | 2020-06-25 16:23:32 +0530 | [diff] [blame] | 52 | <a href="/osm/nslcm/v1/subscriptions">NS_Subs </a> |
| tierno | f27c79b | 2018-03-12 17:08:42 +0100 | [diff] [blame] | 53 | <a href="/osm/admin/v1/tokens?METHOD=DELETE">logout </a> |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 54 | </div> |
| 55 | </div> |
| 56 | """ |
| 57 | |
| 58 | html_body = """ |
| 59 | <h1>{item}</h1> |
| 60 | """ |
| 61 | |
| 62 | html_end = """ |
| 63 | </body> |
| tierno | 2236d20 | 2018-05-16 19:05:16 +0200 | [diff] [blame] | 64 | </html> |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 65 | """ |
| 66 | |
| 67 | html_body_error = "<h2> Error <pre>{}</pre> </h2>" |
| 68 | |
| 69 | |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 70 | html_auth2 = """ |
| 71 | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
| 72 | <html> |
| 73 | <head><META http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
| 74 | <link href="/osm/static/style.css" rel="stylesheet"> |
| 75 | <title>OSM Login</title> |
| K Sai Kiran | 8748af5 | 2020-06-25 16:23:32 +0530 | [diff] [blame] | 76 | <link rel="shortcut icon" href="/osm/static/favicon.ico"> |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 77 | </head> |
| 78 | <body> |
| 79 | <div id="osm_header"> |
| 80 | <div> |
| 81 | <a href="https://osm.etsi.org"> <h1><img src="/osm/static/OSM-logo.png" style="vertical-align:middle"></h1> </a> |
| 82 | </div> |
| 83 | </div> |
| 84 | <div id="osm_error_message"> |
| 85 | <h1>{error}</h1> |
| 86 | </div> |
| 87 | <div class="gerritBody" id="osm_body"> |
| 88 | <h1>Sign in to OSM</h1> |
| tierno | f27c79b | 2018-03-12 17:08:42 +0100 | [diff] [blame] | 89 | <form action="/osm/admin/v1/tokens" id="login_form" method="POST"> |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 90 | <table style="border: 0;"> |
| 91 | <tr><th>Username</th><td><input id="f_user" name="username" size="25" tabindex="1" type="text"></td></tr> |
| 92 | <tr><th>Password</th><td><input id="f_pass" name="password" size="25" tabindex="2" type="password"></td></tr> |
| 93 | <tr><td><input tabindex="3" type="submit" value="Sign In"></td></tr> |
| 94 | </table> |
| 95 | </form> |
| 96 | <div style="clear: both; margin-top: 15px; padding-top: 2px; margin-bottom: 15px;"> |
| 97 | <div id="osm_footer"> |
| 98 | <div></div> |
| 99 | </div> |
| 100 | </div> |
| 101 | </div> |
| 102 | <script src="/osm/static/login.js"> </script> |
| 103 | </body> |
| 104 | </html> |
| 105 | """ |
| 106 | |
| 107 | html_upload_body = """ |
| 108 | <form action="/osm{}" method="post" enctype="multipart/form-data"> |
| 109 | <h3> <table style="border: 0;"> <tr> |
| 110 | <td> Upload {} descriptor (tar.gz) file: <input type="file" name="descriptor_file"/> </td> |
| 111 | <td> <input type="submit" value="Upload"/> </td> |
| 112 | </tr> </table> </h3> |
| 113 | </form> |
| 114 | """ |
| 115 | |
| tierno | 65acb4d | 2018-04-06 16:42:40 +0200 | [diff] [blame] | 116 | html_nslcmop_body = """ |
| 117 | <a href="/osm/nslcm/v1/ns_lcm_op_occs?nsInstanceId={id}">nslcm operations </a> |
| tierno | f759d82 | 2018-06-11 18:54:54 +0200 | [diff] [blame] | 118 | <a href="/osm/nslcm/v1/vnf_instances?nsr-id-ref={id}">VNFRS </a> |
| tierno | 65acb4d | 2018-04-06 16:42:40 +0200 | [diff] [blame] | 119 | <form action="/osm/nslcm/v1/ns_instances/{id}/terminate" method="post" enctype="multipart/form-data"> |
| 120 | <h3> <table style="border: 0;"> <tr> |
| 121 | <td> <input type="submit" value="Terminate"/> </td> |
| 122 | </tr> </table> </h3> |
| 123 | </form> |
| 124 | """ |
| 125 | |
| Felipe Vicens | 07f3172 | 2018-10-29 15:16:44 +0100 | [diff] [blame] | 126 | html_nsilcmop_body = """ |
| Felipe Vicens | 126af57 | 2019-06-05 19:13:04 +0200 | [diff] [blame] | 127 | <a href="/osm/nsilcm/v1/nsi_lcm_op_occs?netsliceInstanceId={id}">nsilcm operations </a> |
| Felipe Vicens | 07f3172 | 2018-10-29 15:16:44 +0100 | [diff] [blame] | 128 | <form action="/osm/nsilcm/v1/netslice_instances/{id}/terminate" method="post" enctype="multipart/form-data"> |
| 129 | <h3> <table style="border: 0;"> <tr> |
| 130 | <td> <input type="submit" value="Terminate"/> </td> |
| 131 | </tr> </table> </h3> |
| 132 | </form> |
| 133 | """ |
| 134 | |
| tierno | 74b5358 | 2020-06-18 10:52:37 +0000 | [diff] [blame] | 135 | html_vnfpackage_body = """<a href="/osm/vnfpkgm/v1/vnf_packages/{id}/artifacts">Artifacts </a>""" |
| 136 | html_nspackage_body = """<a href="/osm/nsd/v1/ns_descriptors/{id}/artifacts">Artifacts </a>""" |
| 137 | |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 138 | |
| tierno | 701018c | 2019-06-25 11:13:14 +0000 | [diff] [blame] | 139 | def format(data, request, response, toke_info): |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 140 | """ |
| 141 | Format a nice html response, depending on the data |
| 142 | :param data: |
| 143 | :param request: cherrypy request |
| 144 | :param response: cherrypy response |
| 145 | :return: string with teh html response |
| 146 | """ |
| 147 | response.headers["Content-Type"] = 'text/html' |
| 148 | if response.status == HTTPStatus.UNAUTHORIZED.value: |
| 149 | if response.headers.get("WWW-Authenticate") and request.config.get("auth.allow_basic_authentication"): |
| 150 | response.headers["WWW-Authenticate"] = "Basic" + response.headers["WWW-Authenticate"][6:] |
| 151 | return |
| 152 | else: |
| 153 | return html_auth2.format(error=data) |
| tierno | 5792d7d | 2019-08-30 15:37:12 +0000 | [diff] [blame] | 154 | if request.path_info in ("/version", "/system"): |
| 155 | return "<pre>" + yaml.safe_dump(data, explicit_start=False, indent=4, default_flow_style=False) + "</pre>" |
| tierno | 2345387 | 2020-07-21 12:01:02 +0000 | [diff] [blame] | 156 | body = html_body.format(item=html_escape(request.path_info)) |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 157 | if response.status and response.status > 202: |
| tierno | 2345387 | 2020-07-21 12:01:02 +0000 | [diff] [blame] | 158 | # input request.path_info (URL) can contain XSS that are translated into output error detail |
| 159 | body += html_body_error.format(html_escape( |
| 160 | yaml.safe_dump(data, explicit_start=True, indent=4, default_flow_style=False))) |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 161 | elif isinstance(data, (list, tuple)): |
| tierno | b24258a | 2018-10-04 18:39:49 +0200 | [diff] [blame] | 162 | if request.path_info == "/vnfpkgm/v1/vnf_packages": |
| tierno | c67b0e9 | 2019-11-05 12:45:29 +0000 | [diff] [blame] | 163 | body += html_upload_body.format(request.path_info + "_content", "VNFD") |
| tierno | b24258a | 2018-10-04 18:39:49 +0200 | [diff] [blame] | 164 | elif request.path_info == "/nsd/v1/ns_descriptors": |
| 165 | body += html_upload_body.format(request.path_info + "_content", "NSD") |
| Felipe Vicens | b57758d | 2018-10-16 16:00:20 +0200 | [diff] [blame] | 166 | elif request.path_info == "/nst/v1/nst_templates": |
| 167 | body += html_upload_body.format(request.path_info + "_content", "NSTD") |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 168 | for k in data: |
| tierno | f27c79b | 2018-03-12 17:08:42 +0100 | [diff] [blame] | 169 | if isinstance(k, dict): |
| 170 | data_id = k.pop("_id", None) |
| 171 | elif isinstance(k, str): |
| 172 | data_id = k |
| tierno | ef4e224 | 2018-10-31 17:09:52 +0100 | [diff] [blame] | 173 | body += '<p> <a href="/osm/{url}/{id}">{id}</a>: {t} </p>'.format(url=request.path_info, id=data_id, |
| 174 | t=html_escape(str(k))) |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 175 | elif isinstance(data, dict): |
| 176 | if "Location" in response.headers: |
| 177 | body += '<a href="{}"> show </a>'.format(response.headers["Location"]) |
| 178 | else: |
| tierno | 74b5358 | 2020-06-18 10:52:37 +0000 | [diff] [blame] | 179 | _id = request.path_info[request.path_info.rfind("/")+1:] |
| tierno | 2236d20 | 2018-05-16 19:05:16 +0200 | [diff] [blame] | 180 | body += '<a href="/osm/{}?METHOD=DELETE"> <img src="/osm/static/delete.png" height="25" width="25"> </a>'\ |
| 181 | .format(request.path_info) |
| tierno | 65acb4d | 2018-04-06 16:42:40 +0200 | [diff] [blame] | 182 | if request.path_info.startswith("/nslcm/v1/ns_instances_content/") or \ |
| 183 | request.path_info.startswith("/nslcm/v1/ns_instances/"): |
| tierno | 65acb4d | 2018-04-06 16:42:40 +0200 | [diff] [blame] | 184 | body += html_nslcmop_body.format(id=_id) |
| Felipe Vicens | 07f3172 | 2018-10-29 15:16:44 +0100 | [diff] [blame] | 185 | elif request.path_info.startswith("/nsilcm/v1/netslice_instances_content/") or \ |
| 186 | request.path_info.startswith("/nsilcm/v1/netslice_instances/"): |
| Felipe Vicens | 07f3172 | 2018-10-29 15:16:44 +0100 | [diff] [blame] | 187 | body += html_nsilcmop_body.format(id=_id) |
| tierno | 74b5358 | 2020-06-18 10:52:37 +0000 | [diff] [blame] | 188 | elif request.path_info.startswith("/vnfpkgm/v1/vnf_packages/") or \ |
| 189 | request.path_info.startswith("/vnfpkgm/v1/vnf_packages_content/"): |
| 190 | body += html_vnfpackage_body.format(id=_id) |
| 191 | elif request.path_info.startswith("/nsd/v1/ns_descriptors/") or \ |
| 192 | request.path_info.startswith("/nsd/v1/ns_descriptors_content/"): |
| 193 | body += html_nspackage_body.format(id=_id) |
| tierno | ef4e224 | 2018-10-31 17:09:52 +0100 | [diff] [blame] | 194 | body += "<pre>" + html_escape(yaml.safe_dump(data, explicit_start=True, indent=4, default_flow_style=False)) + \ |
| 195 | "</pre>" |
| tierno | 0f98af5 | 2018-03-19 10:28:22 +0100 | [diff] [blame] | 196 | elif data is None: |
| 197 | if request.method == "DELETE" or "METHOD=DELETE" in request.query_string: |
| 198 | body += "<pre> deleted </pre>" |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 199 | else: |
| tierno | ef4e224 | 2018-10-31 17:09:52 +0100 | [diff] [blame] | 200 | body = html_escape(str(data)) |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 201 | user_text = " " |
| tierno | 701018c | 2019-06-25 11:13:14 +0000 | [diff] [blame] | 202 | if toke_info: |
| 203 | if toke_info.get("username"): |
| 204 | user_text += "user: {}".format(toke_info.get("username")) |
| 205 | if toke_info.get("project_id"): |
| tierno | 19ee3b0 | 2019-08-28 13:30:23 +0000 | [diff] [blame] | 206 | user_text += ", project: {}".format(toke_info.get("project_name")) |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 207 | return html_start.format(user_text) + body + html_end |
| tierno | 2236d20 | 2018-05-16 19:05:16 +0200 | [diff] [blame] | 208 | # yaml.safe_dump(data, explicit_start=True, indent=4, default_flow_style=False) |
| tierno | c94c3df | 2018-02-09 15:38:54 +0100 | [diff] [blame] | 209 | # tags=False, |
| 210 | # encoding='utf-8', allow_unicode=True) |