Merge branch 'jvelilla-roc_auth'

This commit is contained in:
jvelilla
2014-10-02 21:02:06 -03:00
28 changed files with 399 additions and 30 deletions

View File

@@ -10,6 +10,7 @@
<library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/> <library name="http" location="$ISE_LIBRARY\contrib\library\network\protocol\http\http-safe.ecf"/>
<library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/> <library name="json" location="$ISE_LIBRARY\contrib\library\text\parser\json\library\json-safe.ecf" readonly="false"/>
<library name="layout" location="..\layout\layout.ecf"/> <library name="layout" location="..\layout\layout.ecf"/>
<library name="http_authorization" location="$ISE_LIBRARY\contrib\library\network\authentication\http_authorization\http_authorization-safe.ecf" readonly="false"/>
<library name="persistence_mysql" location="..\persistence\implementation\mysql\persistence_mysql.ecf" readonly="false"/> <library name="persistence_mysql" location="..\persistence\implementation\mysql\persistence_mysql.ecf" readonly="false"/>
<library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/> <library name="smarty" location="$ISE_LIBRARY\contrib\library\text\template\smarty\smarty-safe.ecf" readonly="false"/>
<library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/> <library name="wsf" location="$ISE_LIBRARY\contrib\library\web\framework\ewf\wsf\wsf-safe.ecf"/>

View File

@@ -85,6 +85,10 @@ feature {NONE} -- Initialization
create {NODE_MODULE} m.make (Current) create {NODE_MODULE} m.make (Current)
m.enable m.enable
modules.extend (m) modules.extend (m)
create {BASIC_AUTH_MODULE} m.make (Current)
m.enable
modules.extend (m)
end end
build_api_service build_api_service

View File

@@ -0,0 +1,79 @@
note
description: "Summary description for {BASIC_AUTH_MODULE}."
date: "$Date$"
revision: "$Revision$"
class
BASIC_AUTH_MODULE
inherit
CMS_MODULE
create
make
feature {NONE} -- Initialization
make (a_config: CMS_SETUP)
do
name := "basic auth"
version := "1.0"
description := "Service to manage basic authentication"
package := "core"
config := a_config
setup_router
setup_filter
enable
end
feature -- Access
router: WSF_ROUTER
-- Node router.
config: CMS_SETUP
-- Node configuration.
feature -- Implementation
setup_router
-- Setup `router'.
do
create router.make (2)
configure_api_login
configure_api_logoff
end
setup_filter
-- Setup `filter'.
do
add_filter (create {CORS_FILTER})
add_filter (create {BASIC_AUTH_FILTER}.make (config))
end
feature -- Configure Node Resources Routes
configure_api_login
local
l_bal_handler: BASIC_AUTH_LOGIN_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_bal_handler.make (config)
create l_methods
l_methods.enable_get
router.handle_with_request_methods ("/basic_auth_login", l_bal_handler, l_methods)
end
configure_api_logoff
local
l_bal_handler: BASIC_AUTH_LOGOFF_HANDLER
l_methods: WSF_REQUEST_METHODS
do
create l_bal_handler.make (config)
create l_methods
l_methods.enable_get
router.handle_with_request_methods ("/basic_auth_logoff", l_bal_handler, l_methods)
end
end

View File

@@ -0,0 +1,51 @@
note
description: "Summary description for {BASIC_AUTH_FILTER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
BASIC_AUTH_FILTER
inherit
WSF_URI_TEMPLATE_HANDLER
CMS_HANDLER
WSF_FILTER
create
make
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter
local
l_auth: HTTP_AUTHORIZATION
do
log.write_debug (generator + ".execute " )
create l_auth.make (req.http_authorization)
if attached req.raw_header_data as l_raw_data then
log.write_debug (generator + ".execute " + l_raw_data )
end
-- A valid user
if (attached l_auth.type as l_auth_type and then l_auth_type.is_case_insensitive_equal_general ("basic")) and then
attached l_auth.login as l_auth_login and then attached l_auth.password as l_auth_password then
if api_service.login_valid (l_auth_login, l_auth_password) then
if attached api_service.user_by_name (l_auth_login) as l_user then
req.set_execution_variable ("user", l_user)
execute_next (req, res)
else
-- Internal server error
end
else
log.write_error (generator + ".execute login_valid failed for: " + l_auth_login )
execute_next (req, res)
end
else
log.write_error (generator + ".execute Not valid")
execute_next (req, res)
end
end
end

View File

@@ -0,0 +1,28 @@
note
description: "CORS filter"
date: "$Date: 2014-08-08 16:02:11 -0300 (vi., 08 ago. 2014) $"
revision: "$Revision: 95593 $"
class
CORS_FILTER
inherit
WSF_FILTER
feature -- Basic operations
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter.
local
l_header: HTTP_HEADER
do
create l_header.make
-- l_header.add_header_key_value ("Access-Control-Allow-Origin", "localhost")
l_header.add_header_key_value ("Access-Control-Allow-Headers", "*")
l_header.add_header_key_value ("Access-Control-Allow-Methods", "*")
l_header.add_header_key_value ("Access-Control-Allow-Credentials", "true")
res.put_header_lines (l_header)
execute_next (req, res)
end
end

View File

@@ -0,0 +1,62 @@
note
description: "Summary description for {BASIC_AUTH_LOGIN_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
BASIC_AUTH_LOGIN_HANDLER
inherit
CMS_HANDLER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_FILTER
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
execute_next (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
do
log.write_information(generator + ".do_get Processing basic auth login")
if attached {STRING_32} current_user_name (req) as l_user then
(create {CMS_GENERIC_RESPONSE}).new_response_redirect (req, res, req.absolute_script_url("/"))
else
(create {CMS_GENERIC_RESPONSE}).new_response_authenticate (req, res)
end
end
end

View File

@@ -0,0 +1,59 @@
note
description: "Summary description for {BASIC_AUTH_LOGOFF_HANDLER}."
date: "$Date$"
revision: "$Revision$"
class
BASIC_AUTH_LOGOFF_HANDLER
inherit
CMS_HANDLER
WSF_URI_HANDLER
rename
execute as uri_execute,
new_mapping as new_uri_mapping
end
WSF_RESOURCE_HANDLER_HELPER
redefine
do_get
end
REFACTORING_HELPER
create
make
feature -- execute
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
end
uri_execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute request handler.
do
execute_methods (req, res)
end
feature -- HTTP Methods
do_get (req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
local
l_page: CMS_RESPONSE
do
log.write_information(generator + ".do_get Processing basic auth logoff")
if attached req.query_parameter ("prompt") as l_prompt then
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)
else
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "master2/basic_auth/logoff")
l_page.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
l_page.execute
end
end
end

View File

@@ -25,6 +25,26 @@ feature -- Router
deferred deferred
end end
feature -- Filter
filters: detachable LIST[WSF_FILTER]
-- Possibly list of Filter's module.
feature -- Element Change: Filter
add_filter (a_filter: WSF_FILTER)
-- Add a filter `a_filter' to the list of module filters `filters'.
local
l_filters: like filters
do
l_filters := filters
if l_filters = Void then
create {ARRAYED_LIST[WSF_FILTER]}l_filters.make (1)
filters := l_filters
end
l_filters.force (a_filter)
end
feature -- Settings feature -- Settings
enable enable

View File

@@ -71,7 +71,7 @@ feature -- HTTP Methods
if attached {WSF_STRING} req.path_parameter ("id") as l_id then if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_content") create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_content")
l_page.add_variable (l_node.content, "content") l_page.add_variable (l_node.content, "node_content")
l_page.add_variable (l_id.value, "id") l_page.add_variable (l_id.value, "id")
l_page.execute l_page.execute
else else

View File

@@ -70,8 +70,8 @@ feature -- HTTP Methods
if attached {WSF_STRING} req.path_parameter ("id") as l_id then if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_summary") create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_summary")
l_page.add_variable (l_node.summary, "summary")
l_page.add_variable (l_id.value, "id") l_page.add_variable (l_id.value, "id")
l_page.add_variable (l_node.summary, "node_summary")
l_page.execute l_page.execute
else else
do_error (req, res, l_id) do_error (req, res, l_id)

View File

@@ -70,20 +70,14 @@ feature -- HTTP Methods
if attached {WSF_STRING} req.path_parameter ("id") as l_id then if attached {WSF_STRING} req.path_parameter ("id") as l_id then
if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then if l_id.is_integer and then attached {CMS_NODE} api_service.node (l_id.integer_value) as l_node then
create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_title") create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, setup, "modules/node_title")
l_page.add_variable (setup.is_html, "html") l_page.add_variable (l_node.title, "node_title")
l_page.add_variable (setup.is_web, "web")
l_page.add_variable (l_node.title, "title")
l_page.add_variable (l_id.value, "id") l_page.add_variable (l_id.value, "id")
l_page.execute l_page.execute
else else
do_error (req, res, l_id) do_error (req, res, l_id)
end end
else else
to_implement ("Check how to implement API error") (create {ERROR_500_CMS_RESPONSE}.make (req, res, setup, "master2/error")).execute
-- create l_page.make (req, "master2/error")
-- l_page.set_value ("500", "code")
-- l_page.set_value (req.absolute_script_url (req.path_info), "request")
-- l_page.send_to (res)
end end
else else
(create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res) (create {CMS_GENERIC_RESPONSE}).new_response_unauthorized (req, res)

View File

@@ -11,12 +11,21 @@ class
inherit inherit
WSF_ROUTED_SKELETON_SERVICE WSF_ROUTED_SKELETON_SERVICE
rename
execute as execute_service
undefine undefine
requires_proxy requires_proxy
redefine redefine
execute_default execute_default
end end
WSF_FILTERED_SERVICE
WSF_FILTER
rename
execute as execute_filter
end
WSF_NO_PROXY_POLICY WSF_NO_PROXY_POLICY
WSF_URI_HELPER_FOR_ROUTED_SERVICE WSF_URI_HELPER_FOR_ROUTED_SERVICE
@@ -37,11 +46,13 @@ feature {NONE} -- Initialization
setup := a_setup setup := a_setup
configuration := a_setup.configuration configuration := a_setup.configuration
modules := a_setup.modules modules := a_setup.modules
create {ARRAYED_LIST[WSF_FILTER]} filters.make (0)
initialize_users initialize_users
initialize_auth_engine initialize_auth_engine
initialize_mailer initialize_mailer
initialize_router initialize_router
initialize_modules initialize_modules
initialize_filter
end end
initialize_users initialize_users
@@ -69,6 +80,9 @@ feature {NONE} -- Initialization
if m.item.is_enabled then if m.item.is_enabled then
router.import (m.item.router) router.import (m.item.router)
end end
if attached m.item.filters as l_m_filters then
filters.append (l_m_filters)
end
end end
configure_api_file_handler configure_api_file_handler
end end
@@ -89,6 +103,7 @@ feature {NONE} -- Initialization
create l_methods create l_methods
l_methods.enable_get l_methods.enable_get
router.handle_with_request_methods ("/", l_root_handler, l_methods) router.handle_with_request_methods ("/", l_root_handler, l_methods)
router.handle_with_request_methods ("", l_root_handler, l_methods)
end end
configure_api_file_handler configure_api_file_handler
@@ -105,6 +120,55 @@ feature {NONE} -- Initialization
router.handle_with_request_methods ("/", fhdl, router.methods_GET) router.handle_with_request_methods ("/", fhdl, router.methods_GET)
end end
feature -- Execute Filter
execute_filter (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Execute the filter.
do
res.put_header_line ("Date: " + (create {HTTP_DATE}.make_now_utc).string)
execute_service (req, res)
end
feature -- Filters
create_filter
-- Create `filter'.
local
f, l_filter: detachable WSF_FILTER
fh: WSF_CUSTOM_HEADER_FILTER
do
l_filter := Void
-- Maintenance
create {WSF_MAINTENANCE_FILTER} f
f.set_next (l_filter)
l_filter := f
if attached filters as l_filters then
across l_filters as c loop
c.item.set_next (l_filter)
l_filter := c.item
end
end
filter := l_filter
end
setup_filter
-- Setup `filter'.
local
f: WSF_FILTER
do
from
f := filter
until
not attached f.next as l_next
loop
f := l_next
end
f.set_next (Current)
end
feature -- Access feature -- Access
@@ -119,10 +183,8 @@ feature -- Access
-- List of possible modules. -- List of possible modules.
-- | Maybe we can compute it (using `setup') instead of using memory. -- | Maybe we can compute it (using `setup') instead of using memory.
feature -- Logging filters: LIST[WSF_FILTER]
-- List of possible filters.
feature -- Notification
feature -- Execution feature -- Execution

View File

@@ -9,6 +9,8 @@ deferred class
inherit inherit
WSF_HANDLER
CMS_REQUEST_UTIL CMS_REQUEST_UTIL
SHARED_LOGGER SHARED_LOGGER

View File

@@ -29,7 +29,7 @@ feature -- Responses
create h.make create h.make
h.put_content_type_text_html h.put_content_type_text_html
h.put_current_date h.put_current_date
h.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, "Basic realm=%"CMS-User%"") h.put_header_key_value ({HTTP_HEADER_NAMES}.header_www_authenticate, "Basic realm=%"CMSRoc-User%"")
res.set_status_code ({HTTP_STATUS_CODE}.unauthorized) res.set_status_code ({HTTP_STATUS_CODE}.unauthorized)
res.put_header_text (h.string) res.put_header_text (h.string)
end end

View File

@@ -178,6 +178,8 @@ feature {NONE} -- Execution
prepare (cms_page) prepare (cms_page)
create page.make (theme.page_html (cms_page)) create page.make (theme.page_html (cms_page))
page.set_status_code (status_code) page.set_status_code (status_code)
page.header.put_content_length (page.html.count)
page.header.put_current_date
response.send (page) response.send (page)
on_terminated on_terminated
end end

View File

@@ -30,8 +30,8 @@ feature -- Execution
process process
-- Computed response message. -- Computed response message.
do do
set_title ("CMS") -- set_title ("CMS")
set_page_title (Void) -- set_page_title (Void)
end end
end end

View File

@@ -20,6 +20,7 @@ feature -- Generation
custom_prepare (page: CMS_HTML_PAGE) custom_prepare (page: CMS_HTML_PAGE)
do do
Precursor (page)
page.register_variable (setup.api_service.recent_nodes (0, 5), "nodes") page.register_variable (setup.api_service.recent_nodes (0, 5), "nodes")
end end

View File

@@ -42,10 +42,10 @@ feature -- Access
end end
if attached page.title as l_title then if attached page.title as l_title then
variables.force (l_title, "title") variables.force (l_title, "page_title")
variables.force (l_title, "head_title") variables.force (l_title, "head_title")
else else
variables.force ("", "title") variables.force ("", "page_title")
variables.force ("", "head_title") variables.force ("", "head_title")
end end

View File

@@ -174,6 +174,12 @@ feature -- Filters
f.set_next (l_filter) f.set_next (l_filter)
l_filter := f l_filter := f
-- Authentication
create {AUTHENTICATION_FILTER} f.make (roc_config)
f.set_next (l_filter)
l_filter := f
-- Logger Filter -- Logger Filter
create {LOGGER_FILTER} f.make (roc_config) create {LOGGER_FILTER} f.make (roc_config)
f.set_next (l_filter) f.set_next (l_filter)
@@ -184,10 +190,6 @@ feature -- Filters
f.set_next (l_filter) f.set_next (l_filter)
l_filter := f l_filter := f
-- Authentication
create {AUTHENTICATION_FILTER} f.make (roc_config)
f.set_next (l_filter)
l_filter := f
filter := l_filter filter := l_filter
end end

View File

@@ -52,6 +52,7 @@ feature -- HTTP Methods
if attached req.query_parameter ("prompt") as l_prompt then if attached req.query_parameter ("prompt") as l_prompt then
(create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res) (create {ROC_RESPONSE}.make(req,"")).new_response_unauthorized (req, res)
else else
req.unset_execution_variable ("user")
(create {ROC_RESPONSE}.make(req,"master2/logoff.tpl")).new_response_denied (req, res) (create {ROC_RESPONSE}.make(req,"master2/logoff.tpl")).new_response_denied (req, res)
end end
end end

View File

@@ -1,2 +1,2 @@
port=8088 port=8099
#verbose=true #verbose=true

View File

@@ -12,10 +12,10 @@
{if isset="$user"} {if isset="$user"}
<li><a>{$user/}</a></li> <li><a>{$user/}</a></li>
<li><a title="Node" href="{$host/}/node" rel="node">New Node</a></li> <li><a title="Node" href="{$host/}/node" rel="node">New Node</a></li>
<li><a title="Logoff" href="{$host/}/logoff" rel="logoff">Logoff</a></li> <li><a title="Logoff" href="{$host/}/basic_auth_logoff" rel="logoff">Logoff</a></li>
{/if} {/if}
{unless isset="$user"} {unless isset="$user"}
<li><a title="Login" href="{$host/}/login" rel="login">Login</a></li> <li><a title="Login" href="{$host/}/basic_auth_login" rel="login">Login</a></li>
<li><a title="Register" href="{$host/}/user" rel="register">Register</a></li> <li><a title="Register" href="{$host/}/user" rel="register">Register</a></li>
{/unless} {/unless}
</ul> </ul>

View File

@@ -89,7 +89,7 @@
<div class="row"> <div class="row">
<div class="col-xs-1"> <div class="col-xs-1">
{if isset="$node"} {if isset="$node"}
<label> <span itemprop="description"><a href="{$host/}/node/{$node.id/}/content" rel="node">Summary:</a></span></label> <label> <span itemprop="description"><a href="{$host/}/node/{$node.id/}/summary" rel="node">Summary:</a></span></label>
{/if} {/if}
{unless isset="$node"} {unless isset="$node"}
<label> <span itemprop="description">Summary:</span></label> <label> <span itemprop="description">Summary:</span></label>

View File

@@ -33,7 +33,7 @@
<label> <span itemprop="text">Content:</span> </label> <label> <span itemprop="text">Content:</span> </label>
</div> </div>
<div class="col-xs-7"> <div class="col-xs-7">
<textarea id="content" rows="25" cols="100" class="form-control" name="content" placeholder="Node content" required>{$content/}</textarea> <textarea id="content" rows="25" cols="100" class="form-control" name="content" placeholder="Node content" required>{$node_content/}</textarea>
</div> </div>
</div> </div>

View File

@@ -33,7 +33,7 @@
<label> <span itemprop="text">Summary:</span> </label> <label> <span itemprop="text">Summary:</span> </label>
</div> </div>
<div class="col-xs-7"> <div class="col-xs-7">
<textarea id="summary" rows="3" cols="80" name="summary" placeholder="Node summary" required>{$summary/}</textarea> <textarea id="summary" rows="3" cols="80" name="summary" placeholder="Node summary" required>{$node_summary/}</textarea>
</div> </div>
</div> </div>

View File

@@ -33,7 +33,7 @@
<label> <span itemprop="text">Title:</span> </label> <label> <span itemprop="text">Title:</span> </label>
</div> </div>
<div class="col-xs-7"> <div class="col-xs-7">
<input id="title" type="text" name="title" placeholder="Title" required value="{$title/}"/> <input id="title" type="text" name="title" placeholder="Title" required value="{$node_title/}"/>
</div> </div>
</div> </div>

View File

@@ -15,6 +15,7 @@ inherit
redefine redefine
initialize initialize
end end
WSF_SERVICE WSF_SERVICE
redefine redefine
execute execute