diff --git a/library/server/authentication/http_authorization/example/demo_basic.e b/library/server/authentication/http_authorization/example/demo_basic.e index 0883c8f6..fddbc3ee 100644 --- a/library/server/authentication/http_authorization/example/demo_basic.e +++ b/library/server/authentication/http_authorization/example/demo_basic.e @@ -73,75 +73,163 @@ feature -- Basic operations -- local auth: HTTP_AUTHORIZATION + l_authenticated_username: detachable READABLE_STRING_32 + l_invalid_credential: BOOLEAN do if attached req.http_authorization as l_http_auth then create auth.make (l_http_auth) if attached auth.login as l_login and then is_valid_credential (l_login, auth.password) then - handle_authorized (l_login, req, res) + l_authenticated_username := auth.login else - handle_unauthorized ("ERROR: Invalid credential", req, res) + l_invalid_credential := True end + end + if l_invalid_credential then + handle_unauthorized ("ERROR: Invalid credential", req, res) else - handle_unauthorized ("ERROR: Authentication information is missing ...", req, res) + if l_authenticated_username /= Void then + handle_authenticated (l_authenticated_username, req, res) + elseif req.path_info.same_string_general ("/login") then + handle_unauthorized ("Please provide credential ...", req, res) + elseif req.path_info.starts_with_general ("/protected/") then + -- any "/protected/*" url + handle_unauthorized ("Protected area, please sign in before", req, res) + else + handle_anonymous (req, res) + end end end - handle_authorized (a_username: READABLE_STRING_32; req: WSF_REQUEST; res: WSF_RESPONSE) + handle_authenticated (a_username: READABLE_STRING_32; req: WSF_REQUEST; res: WSF_RESPONSE) -- User `a_username' is authenticated, execute request `req' with response `res'. require valid_username: not a_username.is_empty known_username: is_known_login (a_username) local s: STRING - l_logout_url: STRING + page: WSF_HTML_PAGE_RESPONSE do create s.make_empty - s.append ("Welcome %"") + + append_html_header (req, s) + + s.append ("

The authenticated user is ") s.append (html_encoder.general_encoded_string (a_username)) - s.append ("%" ...
") + s.append ("
...

") - l_logout_url := req.absolute_script_url ("/") - l_logout_url.replace_substring_all ("://", "://_@") -- Hack to clear http authorization, i.e connect with bad username. - s.append ("logout") + append_html_menu (a_username, req, s) + append_html_logout (a_username, req, s) + append_html_footer (req, s) - -- Append the raw header data for information - if attached req.raw_header_data as l_header then - s.append ("
")
-				s.append (l_header)
-				s.append ("
") - end + create page.make + page.set_body (s) + res.send (page) + end - res.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "text/html"], ["Content-Length", s.count.out]>>) - res.put_string (s) + handle_anonymous (req: WSF_REQUEST; res: WSF_RESPONSE) + -- No user is authenticated, execute request `req' with response `res'. + local + s: STRING + page: WSF_HTML_PAGE_RESPONSE + do + create s.make_empty + append_html_header (req, s) + + s.append ("Anonymous visitor ...
") + + append_html_login (req, s) + append_html_menu (Void, req, s) + append_html_footer (req, s) + + create page.make + page.set_body (s) + res.send (page) end handle_unauthorized (a_description: STRING; req: WSF_REQUEST; res: WSF_RESPONSE) - -- Handle forbidden. + -- Restricted page, authenticated user is required. + -- Send `a_description' as part of the response. local h: HTTP_HEADER s: STRING + page: WSF_HTML_PAGE_RESPONSE do create s.make_from_string (a_description) - -- Append the raw header data for information - if attached req.raw_header_data as l_header then - s.append ("
")
-				s.append (l_header)
-				s.append ("
") - end + append_html_login (req, s) + append_html_menu (Void, req, s) + append_html_footer (req, s) - create h.make - h.put_content_type_text_html - h.put_content_length (s.count) - h.put_current_date - h.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, + create page.make + page.set_status_code ({HTTP_STATUS_CODE}.unauthorized) + page.header.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, "Basic realm=%"Please enter a valid username and password (demo [" + html_encoder.encoded_string (demo_credential) + "])%"" --| warning: for this example: a valid credential is provided in the message, of course that for real application. ) - res.set_status_code ({HTTP_STATUS_CODE}.unauthorized) - res.put_header_text (h.string) - res.put_string (s) + page.set_body (s) + res.send (page) end +feature -- Helper + + append_html_header (req: WSF_REQUEST; s: STRING) + -- Append header paragraph to `s'. + do + s.append ("

The current page is " + html_encoder.encoded_string (req.path_info) + "

") + end + + append_html_menu (a_username: detachable READABLE_STRING_32; req: WSF_REQUEST; s: STRING) + -- Append menu to `s'. + -- when an user is authenticated, `a_username' is attached. + do + if a_username /= Void then + s.append ("
  • Your account (displayed only is user is authenticated!)
  • ") + end + s.append ("
  • home
  • ") + s.append ("
  • public area
  • ") + s.append ("
  • protected area
  • ") + end + + append_html_login (req: WSF_REQUEST; s: STRING) + -- Append login link to `s'. + do + s.append ("
  • sign in
  • ") + end + + append_html_logout (a_username: detachable READABLE_STRING_32; req: WSF_REQUEST; s: STRING) + -- Append logout link to `s'. + local + l_logout_url: STRING + do + l_logout_url := req.absolute_script_url ("/login") + l_logout_url.replace_substring_all ("://", "://_@") -- Hack to clear http authorization, i.e connect with bad username "_". + s.append ("
  • logout
  • ") + end + + append_html_footer (req: WSF_REQUEST; s: STRING) + -- Append html footer to `s'. + local + hauth: HTTP_AUTHORIZATION + do + s.append ("
    ") + if attached req.http_authorization as l_http_authorization then + s.append ("Has Authorization: header: ") + create hauth.make (req.http_authorization) + if attached hauth.login as l_login then + s.append (" login=" + html_encoder.encoded_string (l_login)+ "") + end + if attached hauth.password as l_password then + s.append (" password=" + html_encoder.encoded_string (l_password)+ "") + end + s.append ("
    ") + end + if attached req.raw_header_data as l_header then + -- Append the raw header data for information + s.append ("Raw header data:") + s.append ("
    ")
    +				s.append (l_header)
    +				s.append ("
    ") + end + end end