note date: "$Date$" revision: "$Revision$" deferred class IRON_NODE_HANDLER inherit WSF_HANDLER WSF_SELF_DOCUMENTED_HANDLER SHARED_HTML_ENCODER feature -- Change set_iron (i: like iron) do iron := i end feature -- Access iron: IRON_NODE database: IRON_NODE_DATABASE do Result := iron.database end feature -- Access is_authenticated (req: WSF_REQUEST): BOOLEAN do Result := current_user (req) /= Void end current_user (req: WSF_REQUEST): detachable IRON_NODE_USER local l_auth: HTTP_AUTHORIZATION do if req.has_execution_variable ("{IRON_REPO}.user") then if attached {like current_user} req.execution_variable ("{IRON_REPO}.user") as u then Result := u end elseif attached req.http_authorization as l_http_authorization then create l_auth.make (l_http_authorization) if attached l_auth.is_basic and then attached l_auth.login as u and then attached l_auth.password as p and then iron.database.is_valid_credential (u, p) and then attached iron.database.user (u) as l_user then req.set_execution_variable ("{IRON_REPO}.user", l_user) Result := l_user end end end has_iron_version (req: WSF_REQUEST): BOOLEAN do Result := attached {WSF_STRING} req.path_parameter ("version") as p_version and then not p_version.is_empty end iron_version (req: WSF_REQUEST): IRON_NODE_VERSION do if attached {WSF_STRING} req.path_parameter ("version") as p_version and then attached p_version.value as v and then v.is_valid_as_string_8 then create Result.make (v.to_string_8) else create Result.make_default end end feature -- Permission has_permission_to_administrate_versions (req: WSF_REQUEST): BOOLEAN do Result := attached current_user (req) as u and then user_has_permission_to_administrate_versions (u) end has_permission_to_modify_package (req: WSF_REQUEST; a_package: IRON_NODE_PACKAGE): BOOLEAN do Result := attached current_user (req) as u and then user_has_permission_to_modify_package (u, a_package) end has_permission_to_modify_package_version (req: WSF_REQUEST; a_package: IRON_NODE_VERSION_PACKAGE): BOOLEAN do Result := attached current_user (req) as u and then user_has_permission_to_modify_package_version (u, a_package) end feature -- Permission user. user_has_permission_to_administrate_versions (a_user: IRON_NODE_USER): BOOLEAN do Result := user_has_permission (a_user, "admin versions") end user_has_permission_to_modify_package (a_user: IRON_NODE_USER; a_package: IRON_NODE_PACKAGE): BOOLEAN do if attached a_package.owner as o then Result := a_user.same_user (o) or else a_user.is_administrator else Result := user_has_permission (a_user, "modify any package") end end user_has_permission_to_modify_package_version (a_user: IRON_NODE_USER; a_package: IRON_NODE_VERSION_PACKAGE): BOOLEAN do if attached a_package.owner as o then Result := a_user.same_user (o) or else a_user.is_administrator else Result := user_has_permission (a_user, "modify any package version") end end feature -- Permission core. user_has_permission (a_user: IRON_NODE_USER; a_permission: READABLE_STRING_GENERAL): BOOLEAN do if a_user.is_administrator then Result := True elseif attached a_user.roles as l_roles then Result := across l_roles as ic some user_role_has_permission (ic, a_permission) end end end user_role_has_permission (a_role: IRON_NODE_USER_ROLE; a_permission: READABLE_STRING_GENERAL): BOOLEAN do Result := False end feature -- Request: methods method_query_parameter: STRING = "_method" is_method_get (req: WSF_REQUEST): BOOLEAN do Result := req.is_get_request_method end is_method_delete (req: WSF_REQUEST): BOOLEAN do Result := req.is_request_method ({HTTP_REQUEST_METHODS}.method_delete) or else ( req.is_get_request_method and then attached req.query_parameter (method_query_parameter) as m and then m.is_case_insensitive_equal ("delete") ) end is_method_post (req: WSF_REQUEST): BOOLEAN do Result := req.is_post_request_method end is_method_put (req: WSF_REQUEST): BOOLEAN do Result := req.is_request_method ({HTTP_REQUEST_METHODS}.method_put) or else ( req.is_post_request_method and then attached req.query_parameter (method_query_parameter) as m and then m.is_case_insensitive_equal ("put") ) end feature -- Request: accepted content type accepted_content_type_parameter: STRING = "_type" is_content_type_text_html_accepted (req: WSF_REQUEST): BOOLEAN do Result := req.is_content_type_accepted ("text/html") or else ( attached req.query_parameter (accepted_content_type_parameter) as m and then m.is_case_insensitive_equal ("html") ) end is_content_type_application_json_accepted (req: WSF_REQUEST): BOOLEAN do Result := req.is_content_type_accepted ("application/json") or else ( attached req.query_parameter (accepted_content_type_parameter) as m and then m.is_case_insensitive_equal ("json") ) end feature -- Redirection redirect_to_package_view (req: WSF_REQUEST; res: WSF_RESPONSE; a_package: IRON_NODE_VERSION_PACKAGE) local html: IRON_NODE_HTML_RESPONSE do create html.make (req, iron) html.set_location (req.absolute_script_url (iron.package_version_view_web_page (a_package))) res.send (html) end feature -- Download download (a_url: READABLE_STRING_8; cl_path: CELL [detachable PATH]; req: WSF_REQUEST) local cl: LIBCURL_HTTP_CLIENT ctx: HTTP_CLIENT_REQUEST_CONTEXT f: detachable FILE do if attached current_user (req) as l_user then create cl.make if attached cl.new_session (a_url) as l_sess and then l_sess.is_available then create ctx.make l_sess.set_max_redirects (-1) l_sess.set_is_insecure (True) f := new_temporary_output_file ("tmp-download-" + l_user.name) if f /= Void and then f.is_open_write then ctx.set_output_content_file (f) if attached l_sess.get ("", ctx) as resp then cl_path.replace (f.path) end f.close end end end end new_temporary_output_file (n: detachable READABLE_STRING_8): detachable FILE local bp: detachable PATH d: DIRECTORY i: INTEGER do bp := iron.layout.tmp_path create d.make_with_path (bp) if not d.exists then d.recursive_create_dir end if n /= Void then bp := bp.extended ("tmp-download-" + n) else bp := bp.extended ("tmp") end from i := 0 until Result /= Void or i > 100 loop i := i + 1 create {RAW_FILE} Result.make_with_path (bp.appended ("__" + i.out)) if Result.exists then Result := Void else Result.open_write end end ensure Result /= Void implies Result.is_open_write end feature -- Package package_version_from_id_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable IRON_NODE_VERSION_PACKAGE do if attached {WSF_STRING} req.path_parameter (a_name) as s_id and then attached iron.database.version_package (iron_version (req), s_id.value) as l_package then Result := l_package end end -- package_from_id_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable IRON_NODE_PACKAGE -- do -- if -- attached {WSF_STRING} req.path_parameter (a_name) as s_id and then -- attached iron.database.package (s_id.value) as l_package -- then -- Result := l_package -- end -- end feature -- Package form new_package_edit_form (vp: detachable IRON_NODE_VERSION_PACKAGE; req: WSF_REQUEST; validating: BOOLEAN): WSF_FORM local f: WSF_FORM f_id: WSF_FORM_HIDDEN_INPUT f_name: WSF_FORM_TEXT_INPUT f_title: WSF_FORM_TEXT_INPUT f_desc: WSF_FORM_TEXTAREA f_tags: WSF_FORM_TEXT_INPUT f_archive: WSF_FORM_FILE_INPUT f_archive_url: WSF_FORM_TEXT_INPUT f_submit: WSF_FORM_SUBMIT_INPUT f_fieldset: WSF_FORM_FIELD_SET s: STRING_32 do if vp /= Void then create f.make (req.script_url (iron.package_version_update_page (vp)), "edit_package") if validating then create f_id.make ("id") else create f_id.make_with_text ("id", vp.id.to_string_32) end f.extend (f_id) else create f.make (req.script_url (iron.package_version_create_page (iron_version (req))), "create_package") end f.set_multipart_form_data_encoding_type create f_name.make ("name") f_name.set_label ("Name") f_name.set_size (50) f.extend (f_name) create f_title.make ("title") f_title.set_label ("Title") f_title.set_description ("Optional title, if unset, use `name' in user interfaces") f_title.set_size (50) f.extend (f_title) create f_desc.make ("description") f_desc.set_label ("Description") f_desc.set_rows (6) f_desc.set_cols (70) f.extend (f_desc) create f_tags.make ("tags") f_tags.set_label ("Tags") f_tags.set_description ("Comma separated keywords") f_tags.set_size (50) f.extend (f_tags) if vp /= Void then create f_fieldset.make f_fieldset.set_legend ("Associated URIs") f.extend (f_fieldset) f_fieldset.extend_html_text ("Manage associated URIs") end create f_fieldset.make f_fieldset.set_legend ("Associated Archive") create f_archive.make ("archive") f_archive.set_label ("Upload archive file") f_fieldset.extend (f_archive) create f_archive_url.make ("archive-url") f_archive_url.set_label ("Get archive from url") f_archive_url.set_description ("If you have trouble uploading the archive file, the server can download from a public URL.") f_archive_url.set_size (50) f_fieldset.extend (f_archive_url) if vp /= Void and then vp.has_archive then -- f_fieldset.insert_after (create {WSF_FORM_RAW_TEXT}.make ("Has already an archive (" + p.archive_file_size.out + " octets)"), f_archive) f_fieldset.extend_html_text ("Has already an archive (" + vp.archive_file_size.out + " octets)") f_fieldset.extend_html_text ("
Operation not permitted.
%N") if a_package /= Void then s.append ("%N") end if attached req.http_referer as l_referer then s.append ("%N") end Result.set_body (s) end new_not_found_response_message (req: WSF_REQUEST): IRON_NODE_HTML_RESPONSE local s: STRING do Result := new_response_message (req) create s.make_from_string ("Resource not found.
%N") if attached req.http_referer as l_referer then s.append ("%N") end Result.set_body (s) end feature {NONE} -- Implementation url_encoder: URL_ENCODER once create Result end note copyright: "Copyright (c) 1984-2021, Eiffel Software" license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)" licensing_options: "http://www.eiffel.com/licensing" copying: "[ This file is part of Eiffel Software's Eiffel Development Environment. Eiffel Software's Eiffel Development Environment is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2 of the License (available at the URL listed under "license" above). Eiffel Software's Eiffel Development Environment is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Eiffel Software's Eiffel Development Environment; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ]" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end