Fix authenticated role permissions, now it also has all anonymous permissions.
Added permissions on basic auth, to have more control on who can authenticate with basic auth.
Use webapi version of basic auth filter.
For webapi, when authenticated /api/user/ is the same as /api/user/{uid} where uid is the id of current logged in user.
This commit is contained in:
@@ -16,7 +16,9 @@ inherit
|
||||
redefine
|
||||
make,
|
||||
filters,
|
||||
setup_hooks
|
||||
setup_hooks,
|
||||
install,
|
||||
permissions
|
||||
end
|
||||
|
||||
CMS_WITH_WEBAPI
|
||||
@@ -35,6 +37,17 @@ feature {NONE} -- Initialization
|
||||
description := "Service to manage basic authentication"
|
||||
end
|
||||
|
||||
feature {CMS_API} -- Module management
|
||||
|
||||
install (a_api: CMS_API)
|
||||
do
|
||||
Precursor (a_api)
|
||||
if attached a_api.user_api.anonymous_user_role as ano then
|
||||
ano.add_permission (perm_use_basic_auth)
|
||||
a_api.user_api.save_user_role (ano)
|
||||
end
|
||||
end
|
||||
|
||||
feature {CMS_EXECUTION} -- Administration
|
||||
|
||||
webapi: CMS_BASIC_AUTH_MODULE_WEBAPI
|
||||
@@ -46,6 +59,15 @@ feature -- Access
|
||||
|
||||
name: STRING = "basic_auth"
|
||||
|
||||
permissions: LIST [READABLE_STRING_8]
|
||||
-- List of permission ids, used by this module, and declared.
|
||||
do
|
||||
Result := Precursor
|
||||
Result.force ("use basic_auth")
|
||||
end
|
||||
|
||||
perm_use_basic_auth: STRING = "use basic_auth"
|
||||
|
||||
feature -- Access: auth strategy
|
||||
|
||||
login_title: STRING = "Basic Auth"
|
||||
|
||||
@@ -28,7 +28,7 @@ feature -- Access: filter
|
||||
-- Possibly list of Filter's module.
|
||||
do
|
||||
create {ARRAYED_LIST [WSF_FILTER]} Result.make (1)
|
||||
Result.extend (create {CMS_BASIC_AUTH_FILTER}.make (a_api))
|
||||
Result.extend (create {CMS_BASIC_WEBAPI_AUTH_FILTER}.make (a_api))
|
||||
end
|
||||
note
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
|
||||
@@ -38,12 +38,14 @@ feature -- Basic operations
|
||||
api.user_api.is_valid_credential (l_auth_login, l_auth_password) and then
|
||||
attached api.user_api.user_by_name (l_auth_login) as l_user
|
||||
then
|
||||
if api.user_has_permission (l_user, {CMS_BASIC_AUTH_MODULE}.perm_use_basic_auth) then
|
||||
debug ("refactor_fixme")
|
||||
fixme ("Maybe we need to store in the credentials in a shared context SECURITY_CONTEXT")
|
||||
-- req.set_execution_variable ("security_content", create SECURITY_CONTEXT.make (l_user))
|
||||
-- other authentication filters (OpenID, etc) should implement the same approach.
|
||||
end
|
||||
set_current_user (l_user)
|
||||
end
|
||||
else
|
||||
api.logger.put_error (generator + ".execute login_valid failed for: " + l_auth_login, Void)
|
||||
end
|
||||
|
||||
@@ -29,7 +29,9 @@ feature -- Basic operations
|
||||
api.user_api.is_valid_credential (l_auth_login, l_auth_password) and then
|
||||
attached api.user_api.user_by_name (l_auth_login) as l_user
|
||||
then
|
||||
if api.user_has_permission (l_user, {CMS_BASIC_AUTH_MODULE}.perm_use_basic_auth) then
|
||||
api.set_user (l_user)
|
||||
end
|
||||
else
|
||||
-- not authenticated due to bad login or password.
|
||||
end
|
||||
@@ -247,9 +247,9 @@ feature -- Status report
|
||||
do
|
||||
if a_permission = Void then
|
||||
Result := True
|
||||
elseif a_user = Void then
|
||||
Result := user_role_has_permission (anonymous_user_role, a_permission)
|
||||
else
|
||||
Result := user_role_has_permission (anonymous_user_role, a_permission)
|
||||
if not Result and a_user /= Void then
|
||||
if is_admin_user (a_user) then
|
||||
Result := True
|
||||
else
|
||||
@@ -260,6 +260,7 @@ feature -- Status report
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
is_admin_user (u: CMS_USER): BOOLEAN
|
||||
do
|
||||
|
||||
@@ -51,7 +51,7 @@ feature -- Request execution
|
||||
do
|
||||
if attached user_by_uid (a_uid) as l_user then
|
||||
if attached api.user as u then
|
||||
if u.same_as (l_user) or api.user_api.is_admin_user (u) then
|
||||
if u.same_as (l_user) and api.has_permission ("use access_token") then
|
||||
rep := new_access_token_response (l_user, user_access_token (l_user), req, res)
|
||||
if attached {WSF_STRING} req.item ("destination") as dest then
|
||||
rep.set_redirection (dest.url_encoded_value)
|
||||
@@ -77,18 +77,13 @@ feature -- Request execution
|
||||
do
|
||||
if attached user_by_uid (a_uid) as l_user then
|
||||
if attached api.user as u then
|
||||
if u.same_as (l_user) or api.user_api.is_admin_user (u) then
|
||||
if
|
||||
u.same_as (l_user) and api.has_permission ("use access_token")
|
||||
then
|
||||
if attached req.path_parameter ("application") then
|
||||
|
||||
end
|
||||
-- l_access_token := user_access_token (l_user)
|
||||
l_access_token := new_key (40)
|
||||
|
||||
-- if l_access_token /= Void then
|
||||
-- l_access_token := "Updated-" + (create {UUID_GENERATOR}).generate_uuid.out
|
||||
-- else
|
||||
-- l_access_token := "New-" + (create {UUID_GENERATOR}).generate_uuid.out
|
||||
-- end
|
||||
set_user_access_token (l_user, l_access_token)
|
||||
|
||||
rep := new_access_token_response (l_user, l_access_token, req, res)
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
note
|
||||
description: "Summary description for {CMS_CORE_MODULE_WEBAPI}."
|
||||
author: ""
|
||||
date: "$Date$"
|
||||
revision: "$Revision$"
|
||||
|
||||
@@ -25,6 +24,7 @@ feature -- Security
|
||||
Result := Precursor
|
||||
Result.force ("admin users")
|
||||
Result.force ("view users")
|
||||
Result.force ("use access_token")
|
||||
end
|
||||
|
||||
feature {NONE} -- Router/administration
|
||||
@@ -35,11 +35,13 @@ feature {NONE} -- Router/administration
|
||||
l_root: CMS_ROOT_WEBAPI_HANDLER
|
||||
do
|
||||
create l_root.make (a_api)
|
||||
l_root.set_router (a_router)
|
||||
a_router.handle ("", l_root, a_router.methods_get)
|
||||
a_router.handle ("/", l_root, a_router.methods_get)
|
||||
a_router.handle ("/user/{uid}/access_token", create {CMS_ACCESS_TOKEN_WEBAPI_HANDLER}.make (a_api), a_router.methods_get_post)
|
||||
a_router.handle ("/user/{uid}", create {CMS_USER_WEBAPI_HANDLER}.make (a_api), a_router.methods_get)
|
||||
a_router.handle ("/user/", create {CMS_USERS_WEBAPI_HANDLER}.make (a_api), a_router.methods_get_post)
|
||||
a_router.handle ("/user/", create {CMS_USER_WEBAPI_HANDLER}.make (a_api), a_router.methods_get)
|
||||
a_router.handle ("/users/", create {CMS_USERS_WEBAPI_HANDLER}.make (a_api), a_router.methods_get_post)
|
||||
end
|
||||
|
||||
feature -- Access: filter
|
||||
@@ -49,7 +51,6 @@ feature -- Access: filter
|
||||
do
|
||||
create {ARRAYED_LIST [WSF_FILTER]} Result.make (2)
|
||||
Result.extend (create {CMS_ACCESS_TOKEN_WEBAPI_AUTH_FILTER}.make (a_api))
|
||||
Result.extend (create {CMS_BASIC_WEBAPI_AUTH_FILTER}.make (a_api))
|
||||
end
|
||||
|
||||
note
|
||||
|
||||
@@ -14,12 +14,25 @@ inherit
|
||||
create
|
||||
make
|
||||
|
||||
feature -- Access
|
||||
|
||||
router: detachable WSF_ROUTER
|
||||
|
||||
feature -- Element change
|
||||
|
||||
set_router (a_router: like router)
|
||||
do
|
||||
router := a_router
|
||||
end
|
||||
|
||||
feature -- Execution
|
||||
|
||||
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
|
||||
-- Execute handler for `req' and respond in `res'.
|
||||
local
|
||||
rep: HM_WEBAPI_RESPONSE
|
||||
vis: WSF_ROUTER_AGENT_ITERATOR
|
||||
j: JSON_ARRAY
|
||||
do
|
||||
rep := new_response (req, res)
|
||||
rep.add_string_field ("site_name", api.setup.site_name)
|
||||
@@ -28,6 +41,44 @@ feature -- Execution
|
||||
elseif api.has_permission ("account register") then
|
||||
rep.add_link ("register", Void, api.webapi_path ("/account/register"))
|
||||
end
|
||||
|
||||
-- If query has "router=yes", display basic information about router mapping.
|
||||
-- Note: this may change in the future
|
||||
if
|
||||
attached router as l_router and then
|
||||
attached req.query_parameter ("router") as p_router and then
|
||||
p_router.same_string ("yes")
|
||||
then
|
||||
create j.make_empty
|
||||
create vis
|
||||
vis.on_item_actions.extend (agent (i_item: WSF_ROUTER_ITEM; i_json: JSON_ARRAY)
|
||||
local
|
||||
jo: JSON_OBJECT
|
||||
s: STRING
|
||||
do
|
||||
create jo.make_with_capacity (3)
|
||||
jo.put_string (i_item.mapping.associated_resource, "resource")
|
||||
create s.make_empty
|
||||
if attached i_item.request_methods as methds and then not methds.is_empty then
|
||||
across
|
||||
methds as ic
|
||||
loop
|
||||
if not s.is_empty then
|
||||
s.extend (',')
|
||||
end
|
||||
s.append (ic.item)
|
||||
end
|
||||
jo.put_string (s, "request_methods")
|
||||
else
|
||||
s.append ("*")
|
||||
end
|
||||
|
||||
jo.put_string (i_item.mapping.description, "description")
|
||||
i_json.extend (jo)
|
||||
end(?, j))
|
||||
vis.process_router (l_router)
|
||||
rep.add_string_field ("routing", j.representation)
|
||||
end
|
||||
rep.add_self (req.percent_encoded_path_info)
|
||||
rep.execute
|
||||
end
|
||||
|
||||
@@ -41,6 +41,10 @@ feature -- Execution
|
||||
else
|
||||
l_user := api.user_api.user_by_name (p_uid.value)
|
||||
end
|
||||
else
|
||||
-- if uid is not give, use current user if any
|
||||
l_user := u
|
||||
end
|
||||
-- if l_user = Void and p_uid.is_case_insensitive_equal ("me") then
|
||||
-- l_user := u
|
||||
-- end
|
||||
@@ -73,10 +77,6 @@ feature -- Execution
|
||||
rep := new_error_response ("Not found", req, res)
|
||||
rep.set_status_code ({HTTP_STATUS_CODE}.not_found)
|
||||
end
|
||||
else
|
||||
rep := new_error_response ("Bad request", req, res)
|
||||
rep.set_status_code ({HTTP_STATUS_CODE}.bad_request)
|
||||
end
|
||||
else
|
||||
-- FIXME: use specific Web API response!
|
||||
rep := new_access_denied_error_response (Void, req, res)
|
||||
|
||||
@@ -51,13 +51,13 @@ feature {CMS_API, CMS_MODULE_ADMINISTRATION, CMS_MODULE_WEBAPI} -- Access: API
|
||||
|
||||
feature -- Status
|
||||
|
||||
is_initialized: BOOLEAN
|
||||
frozen is_initialized: BOOLEAN
|
||||
-- Is Current module initialized?
|
||||
do
|
||||
Result := module.is_initialized
|
||||
end
|
||||
|
||||
is_enabled: BOOLEAN
|
||||
frozen is_enabled: BOOLEAN
|
||||
-- Is Current module enabled?
|
||||
do
|
||||
Result := module.is_enabled
|
||||
|
||||
Reference in New Issue
Block a user