Files
ROC/src/service/user/cms_user_api.e
Jocelyn Fiat 3496536751 Added CMS_API.request: WSF_REQUEST to ease dev of ROC CMS code.
- Removed CMS_REQUEST_UTIL
  - centralize a few request related code into CMS_API
Added CMS_API.user, CMS_API.set_user (CMS_USER), ... and user related routines.

Refactored Auth related code
  - added various abstractions to factorize implementation and harmonize solutions.
  - revisited the logout strategy.
  - updated the account info page, and remove info user should not care about.
  - simplified the process, and encourage auth module to follow same design.

Added CMS_LINK helper routines to modify the related query string.
Removed CMS_USER.profile (and related routines)
   - It was not used so far.
   - it will probably a specific module later, if needed.

Update various module to avoid fetching user from sql directly, and let this task to CMS_USER_API.

Removed CMS_NODE_API.node_author (a_node: CMS_NODE): detachable CMS_USER,
   - as the info is already in CMS_NODE.author

Added CMS_RESPONSE.redirection_delay, if ever one code want to redirect after a few seconds.
Added the request uri info to the not found cms response.
2016-01-29 21:58:49 +01:00

413 lines
10 KiB
Plaintext

note
description: "API providing user related features."
date: "$Date: 2015-02-13 13:08:13 +0100 (ven., 13 févr. 2015) $"
revision: "$Revision: 96616 $"
class
CMS_USER_API
inherit
CMS_MODULE_API
REFACTORING_HELPER
create
make
feature -- Access: user
user_by_id (a_id: like {CMS_USER}.id): detachable CMS_USER
-- User by id `a_id', if any.
do
Result := storage.user_by_id (a_id)
end
user_by_name (a_username: READABLE_STRING_32): detachable CMS_USER
-- User by name `a_user_name', if any.
do
Result := storage.user_by_name (a_username)
end
user_by_email (a_email: READABLE_STRING_32): detachable CMS_USER
-- User by email `a_email', if any.
do
Result := storage.user_by_email (a_email)
end
user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER
-- User by activation token `a_token'.
do
Result := storage.user_by_activation_token (a_token)
end
user_by_password_token (a_token: READABLE_STRING_32): detachable CMS_USER
-- User by password token `a_token'.
do
Result := storage.user_by_password_token (a_token)
end
users_count: INTEGER
-- Number of users.
do
Result := storage.users_count
end
recent_users (params: CMS_DATA_QUERY_PARAMETERS): ITERABLE [CMS_USER]
-- List of the `a_rows' most recent users starting from `a_offset'.
do
Result := storage.recent_users (params.offset.to_integer_32, params.size.to_integer_32)
end
feature -- Change User
new_user (a_user: CMS_USER)
-- Add a new user `a_user'.
require
no_id: not a_user.has_id
no_hashed_password: a_user.hashed_password = Void
do
reset_error
if
attached a_user.email as l_email
then
storage.new_user (a_user)
error_handler.append (storage.error_handler)
else
error_handler.add_custom_error (0, "bad new user request", "Missing password or email to create new user!")
end
end
update_user (a_user: CMS_USER)
-- Update user `a_user'.
require
has_id: a_user.has_id
do
reset_error
storage.update_user (a_user)
error_handler.append (storage.error_handler)
end
delete_user (a_user: CMS_USER)
-- Delete user `a_user'.
require
has_id: a_user.has_id
do
reset_error
storage.delete_user (a_user)
error_handler.append (storage.error_handler)
end
feature -- Status report
is_valid_credential (a_auth_login, a_auth_password: READABLE_STRING_32): BOOLEAN
-- Is the credentials `a_auth_login' and `a_auth_password' valid?
do
Result := storage.is_valid_credential (a_auth_login, a_auth_password)
end
user_has_permission (a_user: detachable CMS_USER; a_permission: detachable READABLE_STRING_GENERAL): BOOLEAN
-- Anonymous or user `a_user' has permission for `a_permission'?
--| `a_permission' could be for instance "create page".
do
if a_permission = Void then
Result := True
elseif a_user = Void then
Result := user_role_has_permission (anonymous_user_role, a_permission)
else
if is_admin_user (a_user) then
Result := True
else
Result := user_role_has_permission (authenticated_user_role, a_permission)
if not Result then
Result := across user_roles (a_user) as ic some user_role_has_permission (ic.item, a_permission) end
end
end
end
end
is_admin_user (u: CMS_USER): BOOLEAN
do
Result := u.id = 1
end
user_roles (a_user: CMS_USER): LIST [CMS_USER_ROLE]
local
l_roles: detachable LIST [CMS_USER_ROLE]
do
l_roles := a_user.roles
if l_roles = Void then
-- Fill user with its roles.
create {ARRAYED_LIST [CMS_USER_ROLE]} l_roles.make (0)
l_roles := storage.user_roles_for (a_user)
end
Result := l_roles
end
feature -- User roles.
anonymous_user_role: CMS_USER_ROLE
do
if attached user_role_by_id (1) as l_anonymous then
Result := l_anonymous
else
create Result.make ("anonymous")
end
end
authenticated_user_role: CMS_USER_ROLE
do
if attached user_role_by_id (2) as l_authenticated then
Result := l_authenticated
else
create Result.make ("authenticated")
end
end
user_role_has_permission (a_role: CMS_USER_ROLE; a_permission: READABLE_STRING_GENERAL): BOOLEAN
do
Result := a_role.has_permission (a_permission)
end
user_role_by_id (a_id: like {CMS_USER_ROLE}.id): detachable CMS_USER_ROLE
-- Retrieve a `Role' represented by an id `a_id' if any.
do
Result := storage.user_role_by_id (a_id)
end
user_role_by_name (a_name: READABLE_STRING_GENERAL): detachable CMS_USER_ROLE
-- Retrieve a `Role' represented by a name `a_name' if any.
do
Result := storage.user_role_by_name (a_name)
end
role_permissions: HASH_TABLE [LIST [READABLE_STRING_8], STRING_8]
-- Possible known permissions indexed by modules.
local
lst, l_used_permissions: LIST [READABLE_STRING_8]
do
create Result.make (cms_api.enabled_modules.count + 1)
l_used_permissions := storage.role_permissions
across
cms_api.enabled_modules as ic
loop
lst := ic.item.permissions
Result.force (lst, ic.item.name)
across
lst as p_ic
loop
from
l_used_permissions.start
until
l_used_permissions.after
loop
if l_used_permissions.item.is_case_insensitive_equal (p_ic.item) then
l_used_permissions.remove
l_used_permissions.finish
end
l_used_permissions.forth
end
end
if not l_used_permissions.is_empty then
Result.force (l_used_permissions, "")
end
end
end
roles: LIST [CMS_USER_ROLE]
-- List of possible roles.
do
Result := storage.user_roles
end
effective_roles: LIST [CMS_USER_ROLE]
-- List of possible roles, apart from anonymous and authenticated roles that are special.
local
l_roles: like roles
r: CMS_USER_ROLE
do
l_roles := storage.user_roles
create {ARRAYED_LIST [CMS_USER_ROLE]} Result.make (l_roles.count)
across
l_roles as ic
loop
r := ic.item
if r.same_user_role (anonymous_user_role) or r.same_user_role (authenticated_user_role) then
-- Ignore
else
Result.force (r)
end
end
end
roles_count: INTEGER
-- Number of roles
do
Result := storage.user_roles.count
end
feature -- Change User role
save_user_role (a_user_role: CMS_USER_ROLE)
do
reset_error
storage.save_user_role (a_user_role)
error_handler.append (storage.error_handler)
end
unassign_role_from_user (a_role: CMS_USER_ROLE; a_user: CMS_USER; )
-- Unassign user_role `a_role' to user `a_user'.
do
reset_error
storage.unassign_role_from_user (a_role, a_user)
error_handler.append (storage.error_handler)
end
assign_role_to_user (a_role: CMS_USER_ROLE; a_user: CMS_USER; )
-- Assign user_role `a_role' to user `a_user'.
do
reset_error
storage.assign_role_to_user (a_role, a_user)
error_handler.append (storage.error_handler)
end
delete_role (a_role: CMS_USER_ROLE)
do
reset_error
storage.delete_role (a_role)
error_handler.append (storage.error_handler)
end
feature -- User Activation
new_activation (a_token: READABLE_STRING_32; a_id: INTEGER_64)
-- Save activation token `a_token', for the user with the id `a_id'.
do
storage.save_activation (a_token, a_id)
end
feature -- User Password Recovery
new_password (a_token: READABLE_STRING_32; a_id: INTEGER_64)
-- Save password token `a_token', for the user with the id `a_id'.
do
storage.save_password (a_token, a_id)
end
remove_password (a_token: READABLE_STRING_32)
-- Remove password token `a_token', from the storage.
do
storage.remove_password (a_token)
end
feature -- User status
not_active: INTEGER = 0
-- The user is not active.
active: INTEGER = 1
-- The user is active
Trashed: INTEGER = -1
-- The user is trashed (soft delete), ready to be deleted/destroyed from storage.
feature -- Access - Temp User
temp_users_count: INTEGER
-- Number of pending users.
--! to be accepted or rehected
do
Result := storage.temp_users_count
end
temp_user_by_name (a_username: READABLE_STRING_GENERAL): detachable CMS_USER
-- User by name `a_user_name', if any.
do
Result := storage.temp_user_by_name (a_username.as_string_32)
end
temp_user_by_email (a_email: READABLE_STRING_8): detachable CMS_USER
-- User by email `a_email', if any.
do
Result := storage.temp_user_by_email (a_email)
end
temp_user_by_activation_token (a_token: READABLE_STRING_32): detachable CMS_USER
-- User by activation token `a_token'.
do
Result := storage.temp_user_by_activation_token (a_token)
end
temp_recent_users (params: CMS_DATA_QUERY_PARAMETERS): ITERABLE [CMS_TEMP_USER]
-- List of the `a_rows' most recent users starting from `a_offset'.
do
Result := storage.temp_recent_users (params.offset.to_integer_32, params.size.to_integer_32)
end
token_by_temp_user_id (a_id: like {CMS_USER}.id): detachable STRING
do
Result := storage.token_by_temp_user_id (a_id)
end
feature -- Change Temp User
new_user_from_temp_user (a_user: CMS_TEMP_USER)
-- Add a new user `a_user'.
require
no_id: not a_user.has_id
has_hashed_password: a_user.hashed_password /= Void
has_sal: a_user.salt /= Void
do
reset_error
if
attached a_user.hashed_password as l_password and then
attached a_user.salt as l_salt and then
attached a_user.email as l_email
then
storage.new_user_from_temp_user (a_user)
error_handler.append (storage.error_handler)
else
error_handler.add_custom_error (0, "bad new user request", "Missing password or email to create new user!")
end
end
new_temp_user (a_user: CMS_TEMP_USER)
-- Add a new user `a_user'.
require
no_id: not a_user.has_id
no_hashed_password: a_user.hashed_password = Void
do
reset_error
if
attached a_user.password as l_password and then
attached a_user.email as l_email
then
storage.new_temp_user (a_user)
error_handler.append (storage.error_handler)
else
error_handler.add_custom_error (0, "bad new user request", "Missing password or email to create new user!")
end
end
remove_activation (a_token: READABLE_STRING_32)
-- Remove activation token `a_token', from the storage.
do
storage.remove_activation (a_token)
end
delete_temp_user (a_user: CMS_TEMP_USER)
-- Delete user `a_user'.
require
has_id: a_user.has_id
do
reset_error
storage.delete_temp_user (a_user)
error_handler.append (storage.error_handler)
end
note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
end