diff --git a/examples/demo/site/modules/auth/scripts/auth_temp_user.sql b/examples/demo/site/modules/auth/scripts/auth_temp_users.sql similarity index 78% rename from examples/demo/site/modules/auth/scripts/auth_temp_user.sql rename to examples/demo/site/modules/auth/scripts/auth_temp_users.sql index 38ae29b..14d42f6 100644 --- a/examples/demo/site/modules/auth/scripts/auth_temp_user.sql +++ b/examples/demo/site/modules/auth/scripts/auth_temp_users.sql @@ -1,6 +1,6 @@ -DROP TABLE IF EXISTS "auth_temp_user"; -CREATE TABLE `auth_temp_user` ( +DROP TABLE IF EXISTS "auth_temp_users"; +CREATE TABLE `auth_temp_users` ( `uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` VARCHAR(100) NOT NULL, `password` VARCHAR(100) NOT NULL, diff --git a/examples/demo/site/modules/auth/templates/block_post_reactivate.tpl b/examples/demo/site/modules/auth/templates/block_post_reactivate.tpl index 09e7206..4142cd3 100644 --- a/examples/demo/site/modules/auth/templates/block_post_reactivate.tpl +++ b/examples/demo/site/modules/auth/templates/block_post_reactivate.tpl @@ -1,3 +1,3 @@
-

We have send you a new activation code, check your email to activate your account.

+

We have send an email to the administrator, with a new activation code to activate the user account.

diff --git a/examples/demo/site/modules/auth/templates/block_post_register.tpl b/examples/demo/site/modules/auth/templates/block_post_register.tpl index c76cbb5..390c6b4 100644 --- a/examples/demo/site/modules/auth/templates/block_post_register.tpl +++ b/examples/demo/site/modules/auth/templates/block_post_register.tpl @@ -1,3 +1,3 @@
-

Thanks for your application, we will review it to activate your account.

+

You have requested an account, we will let you know when you application is approved or rejected.

diff --git a/examples/demo/site/modules/auth/templates/block_register.tpl b/examples/demo/site/modules/auth/templates/block_register.tpl index 2b56ea9..e55b7b1 100644 --- a/examples/demo/site/modules/auth/templates/block_register.tpl +++ b/examples/demo/site/modules/auth/templates/block_register.tpl @@ -1,7 +1,7 @@
- Register Form + Registration
@@ -24,7 +24,7 @@ - + {if isset="$error_application"} {$error_application/}
{/if} diff --git a/library/model/src/user/cms_user.e b/library/model/src/user/cms_user.e index b0dfbec..7879fcc 100644 --- a/library/model/src/user/cms_user.e +++ b/library/model/src/user/cms_user.e @@ -80,6 +80,11 @@ feature -- Access -- active -- trashed + application: detachable STRING_32 + -- User application + + salt: detachable STRING_32 + -- User's password salt. feature -- Access: helper @@ -220,6 +225,24 @@ feature -- Change element set_last_login_date (create {DATE_TIME}.make_now_utc) end + feature -- Element change + + set_application (an_application: like application) + -- Assign `application' with `an_application'. + do + application := an_application + ensure + application_assigned: application = an_application + end + + set_salt (a_salt: like salt) + -- Assign `salt' with `a_salt'. + do + salt := a_salt + ensure + salt_assigned: salt = a_salt + end + feature -- Element change: roles set_roles (lst: like roles) @@ -302,6 +325,6 @@ invariant id_or_name_set: id > 0 or else not name.is_whitespace note - copyright: "2011-2015, Javier Velilla, Jocelyn Fiat, Eiffel Software and others" + copyright: "2011-2016, Javier Velilla, Jocelyn Fiat, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" end diff --git a/modules/auth/cms_auth_api.e b/modules/auth/cms_auth_api.e index 22bbf0d..f4420c8 100644 --- a/modules/auth/cms_auth_api.e +++ b/modules/auth/cms_auth_api.e @@ -49,7 +49,7 @@ feature -- Access feature -- Temp User - new_temp_user (a_user: CMS_TEMPORAL_USER) + new_temp_user (a_user: CMS_USER) -- Add a new user `a_user'. require no_id: not a_user.has_id @@ -73,7 +73,7 @@ feature -- Temp User auth_storage.remove_activation (a_token) end - delete_user (a_user: CMS_TEMPORAL_USER) + delete_user (a_user: CMS_USER) -- Delete user `a_user'. require has_id: a_user.has_id diff --git a/modules/auth/cms_authentication_module.e b/modules/auth/cms_authentication_module.e index b4bba83..156b0ef 100644 --- a/modules/auth/cms_authentication_module.e +++ b/modules/auth/cms_authentication_module.e @@ -7,6 +7,7 @@ class CMS_AUTHENTICATION_MODULE inherit + CMS_MODULE rename module_api as auth_api @@ -50,7 +51,6 @@ feature {NONE} -- Initialization version := "1.0" description := "Authentication module" package := "authentication" - create root_dir.make_current cache_duration := 0 end @@ -64,6 +64,10 @@ feature -- Access do Result := Precursor Result.force ("account register") + Result.force ("account activate") + Result.force ("account reject") + Result.force ("account reactivate") + Result.force ("admin registration") end feature -- Access: docs @@ -81,7 +85,7 @@ feature -- Access: docs Result := cache_duration = 0 end -feature {CMS_API} -- Module Initialization +feature {CMS_API} -- Module Initialization initialize (a_api: CMS_API) -- @@ -95,7 +99,7 @@ feature {CMS_API} -- Module Initialization if attached a_api.storage.as_sql_storage as l_storage_sql then create {CMS_AUTH_STORAGE_SQL} l_user_auth_storage.make (l_storage_sql) else - -- FIXME: in case of NULL storage, should Current be disabled? + -- FIXME: in case of NULL storage, should Current be disabled? create {CMS_AUTH_STORAGE_NULL} l_user_auth_storage end @@ -111,22 +115,21 @@ feature {CMS_API} -- Module Initialization -- Schema if attached api.storage.as_sql_storage as l_sql_storage then if not l_sql_storage.sql_table_exists ("auth_temp_user") then - --| Schema - l_sql_storage.sql_execute_file_script (api.module_resource_location (Current, (create {PATH}.make_from_string ("scripts")).extended ("auth_temp_user.sql")), Void) - + --| Schema + l_sql_storage.sql_execute_file_script (api.module_resource_location (Current, (create {PATH}.make_from_string ("scripts")).extended ("auth_temp_users.sql")), Void) if l_sql_storage.has_error then api.logger.put_error ("Could not initialize database for auth_module", generating_type) end end l_sql_storage.sql_finalize - Precursor {CMS_MODULE}(api) + Precursor {CMS_MODULE} (api) end end feature {CMS_API} -- Access: API auth_api: detachable CMS_AUTH_API - -- + -- feature -- Router @@ -134,21 +137,29 @@ feature -- Router -- do configure_web (a_api, a_router) + configure_web_admin (a_api, a_router) end configure_web (a_api: CMS_API; a_router: WSF_ROUTER) do - a_router.handle ("/account", create {WSF_URI_AGENT_HANDLER}.make (agent handle_account (a_api, ?, ?)), a_router.methods_head_get) - a_router.handle ("/account/roc-login", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login (a_api, ?, ?)), a_router.methods_head_get) - a_router.handle ("/account/roc-logout", create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout (a_api, ?, ?)), a_router.methods_head_get) - a_router.handle ("/account/roc-register", create {WSF_URI_AGENT_HANDLER}.make (agent handle_register (a_api, ?, ?)), a_router.methods_get_post) - a_router.handle ("/account/activate/{token}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_activation (a_api, ?, ?)), a_router.methods_head_get) - a_router.handle ("/account/reject/{token}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_reject (a_api, ?, ?)), a_router.methods_head_get) - a_router.handle ("/account/reactivate", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reactivation (a_api, ?, ?)), a_router.methods_get_post) - a_router.handle ("/account/new-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_new_password (a_api, ?, ?)), a_router.methods_get_post) - a_router.handle ("/account/reset-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reset_password (a_api, ?, ?)), a_router.methods_get_post) - a_router.handle ("/account/change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_change_password (a_api, ?, ?)), a_router.methods_get_post) - a_router.handle ("/account/post-change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_post_change_password (a_api, ?, ?)), a_router.methods_get) + a_router.handle ("/account", create {WSF_URI_AGENT_HANDLER}.make (agent handle_account(a_api, ?, ?)), a_router.methods_head_get) + a_router.handle ("/account/roc-login", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login(a_api, ?, ?)), a_router.methods_head_get) + a_router.handle ("/account/roc-logout", create {WSF_URI_AGENT_HANDLER}.make (agent handle_logout(a_api, ?, ?)), a_router.methods_head_get) + a_router.handle ("/account/roc-register", create {WSF_URI_AGENT_HANDLER}.make (agent handle_register(a_api, ?, ?)), a_router.methods_get_post) + a_router.handle ("/account/activate/{token}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_activation(a_api, ?, ?)), a_router.methods_head_get) + a_router.handle ("/account/reject/{token}", create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (agent handle_reject(a_api, ?, ?)), a_router.methods_head_get) + a_router.handle ("/account/reactivate", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reactivation(a_api, ?, ?)), a_router.methods_get_post) + a_router.handle ("/account/new-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_new_password(a_api, ?, ?)), a_router.methods_get_post) + a_router.handle ("/account/reset-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_reset_password(a_api, ?, ?)), a_router.methods_get_post) + a_router.handle ("/account/change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_change_password(a_api, ?, ?)), a_router.methods_get_post) + a_router.handle ("/account/post-change-password", create {WSF_URI_AGENT_HANDLER}.make (agent handle_post_change_password(a_api, ?, ?)), a_router.methods_get) + end + + + configure_web_admin (a_api: CMS_API; a_router: WSF_ROUTER) + -- Configure router mapping for admin web interface. + do + a_router.handle ("/admin/pending-registrations/", create {WSF_URI_AGENT_HANDLER}.make (agent handle_admin_pending_registrations (?, ?, a_api)), a_router.methods_get) end feature -- Hooks configuration @@ -159,6 +170,7 @@ feature -- Hooks configuration auto_subscribe_to_hooks (a_hooks) a_hooks.subscribe_to_block_hook (Current) a_hooks.subscribe_to_value_table_alter_hook (Current) + a_hooks.subscribe_to_menu_system_alter_hook (Current) end value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE) @@ -174,7 +186,7 @@ feature -- Hooks configuration lnk: CMS_LOCAL_LINK do if attached a_response.user as u then - create lnk.make (u.name, "account" ) + create lnk.make (u.name, "account") lnk.set_weight (97) a_menu_system.primary_menu.extend (lnk) create lnk.make ("Logout", "account/roc-logout") @@ -185,7 +197,11 @@ feature -- Hooks configuration lnk.set_weight (98) a_menu_system.primary_menu.extend (lnk) end - + -- Add the link to the taxonomy to the main menu + if a_response.has_permission ("admin registration") then + create lnk.make ("Registration", "admin/pending-registrations/") + a_menu_system.management_menu.extend (lnk) + end end feature -- Handler @@ -195,7 +211,6 @@ feature -- Handler r: CMS_RESPONSE do create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - if attached template_block ("account_info", r) as l_tpl_block then if attached r.user as l_user then r.set_value (api.user_api.user_roles (l_user), "roles") @@ -237,7 +252,7 @@ feature -- Handler local r: CMS_RESPONSE l_user_api: CMS_USER_API - u: CMS_TEMPORAL_USER + u: CMS_USER l_exist: BOOLEAN es: CMS_AUTHENTICATON_EMAIL_SERVICE l_url_activate: STRING @@ -246,19 +261,10 @@ feature -- Handler l_captcha_passed: BOOLEAN do create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - if - r.has_permission ("account register") and then - attached auth_api as l_auth_api - then + if r.has_permission ("account register") and then attached auth_api as l_auth_api then if req.is_post_request_method then - if - attached {WSF_STRING} req.form_parameter ("name") as l_name and then - attached {WSF_STRING} req.form_parameter ("password") as l_password and then - attached {WSF_STRING} req.form_parameter ("email") as l_email and then - attached {WSF_STRING} req.form_parameter ("application") as l_application - then + if attached {WSF_STRING} req.form_parameter ("name") as l_name and then attached {WSF_STRING} req.form_parameter ("password") as l_password and then attached {WSF_STRING} req.form_parameter ("email") as l_email and then attached {WSF_STRING} req.form_parameter ("application") as l_application then l_user_api := api.user_api - if attached l_user_api.user_by_name (l_name.value) or else attached l_auth_api.user_by_name (l_name.value) then -- Username already exist. r.set_value ("User name already exists!", "error_name") @@ -269,12 +275,8 @@ feature -- Handler r.set_value ("An account is already associated with that email address!", "error_email") l_exist := True end - if attached recaptcha_secret_key (api) as l_recaptcha_key then - if - attached {WSF_STRING} req.form_parameter ("g-recaptcha-response") as l_recaptcha_response and then - is_captcha_verified (l_recaptcha_key, l_recaptcha_response.value) - then + if attached {WSF_STRING} req.form_parameter ("g-recaptcha-response") as l_recaptcha_response and then is_captcha_verified (l_recaptcha_key, l_recaptcha_response.value) then l_captcha_passed := True else --| Bad or missing captcha @@ -284,7 +286,6 @@ feature -- Handler --| reCaptcha is not setup, so no verification l_captcha_passed := True end - if not l_exist then -- New temp user @@ -321,7 +322,6 @@ feature -- Handler create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) r.set_main_content ("You can also contact the webmaster to ask for an account.") end - r.execute end @@ -335,43 +335,44 @@ feature -- Handler if attached auth_api as l_auth_api then l_user_api := api.user_api create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - if attached {WSF_STRING} req.path_parameter ("token") as l_token then + if r.has_permission ("account activate") then + if attached {WSF_STRING} req.path_parameter ("token") as l_token then + if attached {CMS_USER} l_auth_api.user_by_activation_token (l_token.value) as l_user then + -- Delete temporal User + l_auth_api.delete_user (l_user) - if attached {CMS_TEMPORAL_USER} l_auth_api.user_by_activation_token (l_token.value) as l_user then - -- Delete temporal User - l_auth_api.delete_user (l_user) - - -- Valid user_id - l_user.set_id (0) - l_user.mark_active - l_user_api.new_user (l_user) - l_auth_api.remove_activation (l_token.value) - - r.set_main_content ("

The account "+ l_user.name +" has been activated

") - -- Send Email - if attached l_user.email as l_email then - create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) - write_debug_log (generator + ".handle register: send_contact_activation_confirmation_email") - es.send_contact_activation_confirmation_email (l_email, req.absolute_script_url ("")) + -- Valid user_id + l_user.set_id (0) + l_user.mark_active + l_user_api.new_user_from_temporal_user (l_user) + l_auth_api.remove_activation (l_token.value) + r.set_main_content ("

The account " + l_user.name + " has been activated

") + -- Send Email + if attached l_user.email as l_email then + create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) + write_debug_log (generator + ".handle register: send_contact_activation_confirmation_email") + es.send_contact_activation_confirmation_email (l_email, req.absolute_script_url ("")) + end + else + -- the token does not exist, or it was already used. + r.set_status_code ({HTTP_CONSTANTS}.bad_request) + r.set_main_content ("

The token " + l_token.value + " is not valid " + r.link ("Reactivate Account", "account/reactivate", Void) + "

") end + r.execute else - -- the token does not exist, or it was already used. - r.set_status_code ({HTTP_CONSTANTS}.bad_request) - r.set_main_content ("

The token " + l_token.value +" is not valid " + r.link ("Reactivate Account", "account/reactivate", Void) + "

") + create l_ir.make (req, res, api) + l_ir.execute end - r.execute else - create l_ir.make (req, res, api) - l_ir.execute + create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) + r.execute end else create {INTERNAL_SERVER_ERROR_CMS_RESPONSE} r.make (req, res, api) --- r.set_main_content ("...") r.execute end end - handle_reject (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) local r: CMS_RESPONSE @@ -381,25 +382,30 @@ feature -- Handler do if attached auth_api as l_auth_api then create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - if attached {WSF_STRING} req.path_parameter ("token") as l_token then - if attached {CMS_TEMPORAL_USER} l_auth_api.user_by_activation_token (l_token.value) as l_user then - l_auth_api.delete_user (l_user) - r.set_main_content ("

The temporal account for "+ l_user.name +" has been removed

") - -- Send Email - if attached l_user.email as l_email then - create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) - write_debug_log (generator + ".handle register: send_contact_activation_reject_email") - es.send_contact_activation_reject_email (l_email, req.absolute_script_url ("")) + if r.has_permission ("account reject") then + if attached {WSF_STRING} req.path_parameter ("token") as l_token then + if attached {CMS_USER} l_auth_api.user_by_activation_token (l_token.value) as l_user then + l_auth_api.delete_user (l_user) + r.set_main_content ("

The temporal account for " + l_user.name + " has been removed

") + -- Send Email + if attached l_user.email as l_email then + create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) + write_debug_log (generator + ".handle register: send_contact_activation_reject_email") + es.send_contact_activation_reject_email (l_email, req.absolute_script_url ("")) + end + else + -- the token does not exist, or it was already used. + r.set_status_code ({HTTP_CONSTANTS}.bad_request) + r.set_main_content ("

The token " + l_token.value + " is not valid ") end + r.execute else - -- the token does not exist, or it was already used. - r.set_status_code ({HTTP_CONSTANTS}.bad_request) - r.set_main_content ("

The token " + l_token.value +" is not valid ") + create l_ir.make (req, res, api) + l_ir.execute end - r.execute else - create l_ir.make (req, res, api) - l_ir.execute + create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) + r.execute end else create {INTERNAL_SERVER_ERROR_CMS_RESPONSE} r.make (req, res, api) @@ -418,35 +424,38 @@ feature -- Handler do if attached auth_api as l_auth_api then create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - if req.is_post_request_method then - if - attached {WSF_STRING} req.form_parameter ("email") as l_email - then - l_user_api := api.user_api - if attached {CMS_TEMPORAL_USER} l_auth_api.user_by_email (l_email.value) as l_user then - -- User exist create a new token and send a new email. - if l_user.is_active then - r.set_value ("The asociated user to the given email " + l_email.value + " , is already active", "is_active") - r.set_status_code ({HTTP_CONSTANTS}.bad_request) - else - l_token := new_token - l_user_api.new_activation (l_token, l_user.id) - l_url_activate := req.absolute_script_url ("/account/activate/" + l_token) - l_url_reject := req.absolute_script_url ("/account/reject/" + l_token) + if r.has_permission ("account reactivate") then + if req.is_post_request_method then + if attached {WSF_STRING} req.form_parameter ("email") as l_email then + l_user_api := api.user_api + if attached {CMS_USER} l_auth_api.user_by_email (l_email.value) as l_user then + -- User exist create a new token and send a new email. + if l_user.is_active then + r.set_value ("The asociated user to the given email " + l_email.value + " , is already active", "is_active") + r.set_status_code ({HTTP_CONSTANTS}.bad_request) + else + l_token := new_token + l_user_api.new_activation (l_token, l_user.id) + l_url_activate := req.absolute_script_url ("/account/activate/" + l_token) + l_url_reject := req.absolute_script_url ("/account/reject/" + l_token) - -- Send Email to webmaster - if attached l_user.application as l_application then - create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) - write_debug_log (generator + ".handle register: send_register_email") - es.send_account_evaluation (l_user, l_application, l_url_activate, l_url_reject) + -- Send Email to webmaster + if attached l_user.application as l_application then + create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) + write_debug_log (generator + ".handle register: send_register_email") + es.send_account_evaluation (l_user, l_application, l_url_activate, l_url_reject) + end end + else + r.set_value ("The email does not exist or !", "error_email") + r.set_value (l_email.value, "email") + r.set_status_code ({HTTP_CONSTANTS}.bad_request) end - else - r.set_value ("The email does not exist or !", "error_email") - r.set_value (l_email.value, "email") - r.set_status_code ({HTTP_CONSTANTS}.bad_request) end end + else + create {FORBIDDEN_ERROR_CMS_RESPONSE} r.make (req, res, api) + r.execute end else create {INTERNAL_SERVER_ERROR_CMS_RESPONSE} r.make (req, res, api) @@ -466,13 +475,13 @@ feature -- Handler if req.is_post_request_method then l_user_api := api.user_api if attached {WSF_STRING} req.form_parameter ("email") as l_email then - if attached {CMS_USER} l_user_api.user_by_email (l_email.value) as l_user then - -- User exist create a new token and send a new email. + if attached {CMS_USER} l_user_api.user_by_email (l_email.value) as l_user then + -- User exist create a new token and send a new email. l_token := new_token l_user_api.new_password (l_token, l_user.id) l_url := req.absolute_script_url ("/account/reset-password?token=" + l_token) - -- Send Email + -- Send Email create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) write_debug_log (generator + ".handle register: send_contact_password_email") es.send_contact_password_email (l_email.value, l_url) @@ -482,15 +491,13 @@ feature -- Handler r.set_status_code ({HTTP_CONSTANTS}.bad_request) end elseif attached {WSF_STRING} req.form_parameter ("username") as l_username then - if attached {CMS_USER} l_user_api.user_by_name (l_username) as l_user and then - attached l_user.email as l_email - then - -- User exist create a new token and send a new email. + if attached {CMS_USER} l_user_api.user_by_name (l_username) as l_user and then attached l_user.email as l_email then + -- User exist create a new token and send a new email. l_token := new_token l_user_api.new_password (l_token, l_user.id) l_url := req.absolute_script_url ("/account/reset-password?token=" + l_token) - -- Send Email + -- Send Email create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) write_debug_log (generator + ".handle register: send_contact_password_email") es.send_contact_password_email (l_email, l_url) @@ -504,7 +511,6 @@ feature -- Handler r.execute end - handle_reset_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) local r: CMS_RESPONSE @@ -512,24 +518,18 @@ feature -- Handler do create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) l_user_api := api.user_api - if attached {WSF_STRING} req.query_parameter ("token") as l_token then + if attached {WSF_STRING} req.query_parameter ("token") as l_token then r.set_value (l_token.value, "token") - if l_user_api.user_by_password_token (l_token.value) = Void then - r.set_value ("The token " + l_token.value + " is not valid, " + r.link ("click here" , "account/new-password", Void) + " to generate a new token.", "error_token") + if l_user_api.user_by_password_token (l_token.value) = Void then + r.set_value ("The token " + l_token.value + " is not valid, " + r.link ("click here", "account/new-password", Void) + " to generate a new token.", "error_token") r.set_status_code ({HTTP_CONSTANTS}.bad_request) end end - if req.is_post_request_method then - - if - attached {WSF_STRING} req.form_parameter ("token") as l_token and then - attached {WSF_STRING} req.form_parameter ("password") as l_password and then - attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password - then - -- Does the passwords match? + if attached {WSF_STRING} req.form_parameter ("token") as l_token and then attached {WSF_STRING} req.form_parameter ("password") as l_password and then attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password then + -- Does the passwords match? if l_password.value.same_string (l_confirm_password.value) then - -- is the token valid? + -- is the token valid? if attached {CMS_USER} l_user_api.user_by_password_token (l_token.value) as l_user then l_user.set_password (l_password.value) l_user_api.update_user (l_user) @@ -552,22 +552,17 @@ feature -- Handler do create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) l_user_api := api.user_api - if req.is_post_request_method then - if attached r.user as l_user then + if attached r.user as l_user then r.set_value (api.user_api.user_roles (l_user), "roles") - if - attached {WSF_STRING} req.form_parameter ("password") as l_password and then - attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password and then - l_password.value.same_string (l_confirm_password.value) - then - -- Does the passwords match? + if attached {WSF_STRING} req.form_parameter ("password") as l_password and then attached {WSF_STRING} req.form_parameter ("confirm_password") as l_confirm_password and then l_password.value.same_string (l_confirm_password.value) then + -- Does the passwords match? l_user.set_password (l_password.value) l_user_api.update_user (l_user) r.set_redirection (req.absolute_script_url ("/account/post-change-password")) else if attached template_block ("account_info", r) as l_tpl_block then --- r.set_value (l_user, "user") + -- r.set_value (l_user, "user") r.set_value ("Passwords Don't Match", "error_password") r.set_status_code ({HTTP_CONSTANTS}.bad_request) r.add_block (l_tpl_block, "content") @@ -589,11 +584,21 @@ feature -- Handler r.execute end + + handle_admin_pending_registrations (req: WSF_REQUEST; res: WSF_RESPONSE; api: CMS_API) + local + l_page: CMS_RESPONSE + lnk: CMS_LOCAL_LINK + do + create {GENERIC_VIEW_CMS_RESPONSE} l_page.make (req, res, api) + l_page.execute + end + block_list: ITERABLE [like {CMS_BLOCK}.name] local l_string: STRING do - Result := <<"register", "reactivate", "new_password", "reset_password">> + Result := <<"register", "reactivate", "new_password", "reset_password", "registration">> debug ("roc") create l_string.make_empty across @@ -602,32 +607,22 @@ feature -- Handler l_string.append (ic.item) l_string.append_character (' ') end - write_debug_log (generator + ".block_list:" + l_string ) + write_debug_log (generator + ".block_list:" + l_string) end end get_block_view (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) do - if - a_block_id.is_case_insensitive_equal_general ("register") and then - a_response.location.starts_with ("account/roc-register") - then + if a_block_id.is_case_insensitive_equal_general ("register") and then a_response.location.starts_with ("account/roc-register") then get_block_view_register (a_block_id, a_response) - elseif - a_block_id.is_case_insensitive_equal_general ("reactivate") and then - a_response.location.starts_with ("account/reactivate") - then + elseif a_block_id.is_case_insensitive_equal_general ("reactivate") and then a_response.location.starts_with ("account/reactivate") then get_block_view_reactivate (a_block_id, a_response) - elseif - a_block_id.is_case_insensitive_equal_general ("new_password") and then - a_response.location.starts_with ("account/new-password") - then + elseif a_block_id.is_case_insensitive_equal_general ("new_password") and then a_response.location.starts_with ("account/new-password") then get_block_view_new_password (a_block_id, a_response) - elseif - a_block_id.is_case_insensitive_equal_general ("reset_password") and then - a_response.location.starts_with ("account/reset-password") - then + elseif a_block_id.is_case_insensitive_equal_general ("reset_password") and then a_response.location.starts_with ("account/reset-password") then get_block_view_reset_password (a_block_id, a_response) + elseif a_block_id.is_case_insensitive_equal_general ("registration") and then a_response.location.starts_with ("admin/pending-registrations") then + get_block_view_registration (a_block_id, a_response) end end @@ -643,10 +638,13 @@ feature {NONE} -- Token Generation create l_security l_token := l_security.token create l_encode - from until l_token.same_string (l_encode.encoded_string (l_token)) loop - -- Loop ensure that we have a security token that does not contain characters that need encoding. - -- We cannot simply to an encode-decode because the email sent to the user will contain an encoded token - -- but the user will need to use an unencoded token if activation has to be done manually. + from + until + l_token.same_string (l_encode.encoded_string (l_token)) + loop + -- Loop ensure that we have a security token that does not contain characters that need encoding. + -- We cannot simply to an encode-decode because the email sent to the user will contain an encoded token + -- but the user will need to use an unencoded token if activation has to be done manually. l_token := l_security.token end Result := l_token @@ -661,7 +659,6 @@ feature {NONE} -- Helpers do create p.make_from_string ("templates") p := p.extended ("block_").appended (a_block_id).appended_with_extension ("tpl") - p := a_response.api.module_theme_resource_location (Current, p) if p /= Void then if attached p.entry as e then @@ -674,27 +671,6 @@ feature {NONE} -- Helpers feature {NONE} -- Block views --- get_block_view_login (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) --- local ----- vals: CMS_VALUE_TABLE --- do --- if attached template_block (a_block_id, a_response) as l_tpl_block then ----- create vals.make (1) ----- -- add the variable to the block ----- value_table_alter (vals, a_response) ----- across ----- vals as ic ----- loop ----- l_tpl_block.set_value (ic.item, ic.key) ----- end --- a_response.put_required_block (l_tpl_block, "content") --- else --- debug ("cms") --- a_response.add_warning_message ("Error with block [" + a_block_id + "]") --- end --- end --- end - get_block_view_register (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) do if a_response.has_permission ("account register") then @@ -712,10 +688,10 @@ feature {NONE} -- Block views elseif a_response.request.is_post_request_method then if a_response.values.has ("error_name") or else a_response.values.has ("error_email") then if attached template_block (a_block_id, a_response) as l_tpl_block then - -- l_tpl_block.set_value (a_response.values.item ("error_name"), "error_name") - -- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email") - -- l_tpl_block.set_value (a_response.values.item ("email"), "email") - -- l_tpl_block.set_value (a_response.values.item ("name"), "name") + -- l_tpl_block.set_value (a_response.values.item ("error_name"), "error_name") + -- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email") + -- l_tpl_block.set_value (a_response.values.item ("email"), "email") + -- l_tpl_block.set_value (a_response.values.item ("name"), "name") if attached recaptcha_site_key (a_response.api) as l_recaptcha_site_key then l_tpl_block.set_value (l_recaptcha_site_key, "recaptcha_site_key") end @@ -751,9 +727,9 @@ feature {NONE} -- Block views elseif a_response.request.is_post_request_method then if a_response.values.has ("error_email") or else a_response.values.has ("is_active") then if attached template_block (a_block_id, a_response) as l_tpl_block then --- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email") --- l_tpl_block.set_value (a_response.values.item ("email"), "email") --- l_tpl_block.set_value (a_response.values.item ("is_active"), "is_active") + -- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email") + -- l_tpl_block.set_value (a_response.values.item ("email"), "email") + -- l_tpl_block.set_value (a_response.values.item ("is_active"), "is_active") a_response.add_block (l_tpl_block, "content") else debug ("cms") @@ -783,12 +759,12 @@ feature {NONE} -- Block views end end elseif a_response.request.is_post_request_method then - if a_response.values.has ("error_email") or else a_response.values.has ("error_username") then + if a_response.values.has ("error_email") or else a_response.values.has ("error_username") then if attached template_block (a_block_id, a_response) as l_tpl_block then --- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email") --- l_tpl_block.set_value (a_response.values.item ("email"), "email") --- l_tpl_block.set_value (a_response.values.item ("error_username"), "error_username") --- l_tpl_block.set_value (a_response.values.item ("username"), "username") + -- l_tpl_block.set_value (a_response.values.item ("error_email"), "error_email") + -- l_tpl_block.set_value (a_response.values.item ("email"), "email") + -- l_tpl_block.set_value (a_response.values.item ("error_username"), "error_username") + -- l_tpl_block.set_value (a_response.values.item ("username"), "username") a_response.add_block (l_tpl_block, "content") else debug ("cms") @@ -811,8 +787,8 @@ feature {NONE} -- Block views do if a_response.request.is_get_request_method then if attached template_block (a_block_id, a_response) as l_tpl_block then --- l_tpl_block.set_value (a_response.values.item ("token"), "token") --- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token") + -- l_tpl_block.set_value (a_response.values.item ("token"), "token") + -- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token") a_response.add_block (l_tpl_block, "content") else debug ("cms") @@ -820,11 +796,11 @@ feature {NONE} -- Block views end end elseif a_response.request.is_post_request_method then - if a_response.values.has ("error_token") or else a_response.values.has ("error_password") then + if a_response.values.has ("error_token") or else a_response.values.has ("error_password") then if attached template_block (a_block_id, a_response) as l_tpl_block then --- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token") --- l_tpl_block.set_value (a_response.values.item ("error_password"), "error_password") --- l_tpl_block.set_value (a_response.values.item ("token"), "token") + -- l_tpl_block.set_value (a_response.values.item ("error_token"), "error_token") + -- l_tpl_block.set_value (a_response.values.item ("error_password"), "error_password") + -- l_tpl_block.set_value (a_response.values.item ("token"), "token") a_response.add_block (l_tpl_block, "content") else debug ("cms") @@ -843,6 +819,10 @@ feature {NONE} -- Block views end end + get_block_view_registration (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) + do + -- TODO finish + end feature -- Recaptcha @@ -852,10 +832,7 @@ feature -- Recaptcha utf: UTF_CONVERTER do if attached api.module_configuration (Current, Void) as cfg then - if - attached cfg.text_item ("recaptcha.secret_key") as l_recaptcha_key and then - not l_recaptcha_key.is_empty - then + if attached cfg.text_item ("recaptcha.secret_key") as l_recaptcha_key and then not l_recaptcha_key.is_empty then Result := utf.utf_32_string_to_utf_8_string_8 (l_recaptcha_key) end end @@ -867,16 +844,12 @@ feature -- Recaptcha utf: UTF_CONVERTER do if attached api.module_configuration (Current, Void) as cfg then - if - attached cfg.text_item ("recaptcha.site_key") as l_recaptcha_key and then - not l_recaptcha_key.is_empty - then + if attached cfg.text_item ("recaptcha.site_key") as l_recaptcha_key and then not l_recaptcha_key.is_empty then Result := utf.utf_32_string_to_utf_8_string_8 (l_recaptcha_key) end end end - feature -- Response Alter response_alter (a_response: CMS_RESPONSE) @@ -897,21 +870,25 @@ feature {NONE} -- Implementation if not Result and then attached api.errors as l_api_errors then create l_errors.make_empty l_errors.append_character ('%N') - across l_api_errors as ic loop - l_errors.append ( ic.item ) + across + l_api_errors as ic + loop + l_errors.append (ic.item) l_errors.append_character ('%N') end write_error_log (generator + ".is_captcha_verified api_errors [" + l_errors + "]") end end + note copyright: "Copyright (c) 1984-2013, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" 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 - ]" + 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 diff --git a/modules/auth/cms_authenticaton_email_service.e b/modules/auth/cms_authenticaton_email_service.e index 48758f7..bd28c4f 100644 --- a/modules/auth/cms_authenticaton_email_service.e +++ b/modules/auth/cms_authenticaton_email_service.e @@ -101,7 +101,7 @@ feature -- Basic Operations do create l_message.make_from_string (parameters.account_rejected) l_message.replace_substring_all ("$link", a_content) - send_message (contact_email, a_to, parameters.contact_subject_activate, l_message) + send_message (contact_email, a_to, parameters.contact_subject_rejected, l_message) end diff --git a/modules/auth/model/cms_temporal_user.e b/modules/auth/model/cms_temporal_user.e deleted file mode 100644 index 4ea4af4..0000000 --- a/modules/auth/model/cms_temporal_user.e +++ /dev/null @@ -1,32 +0,0 @@ -note - description: "Summary description for {CMS_TEMPORAL_USER}." - date: "$Date$" - revision: "$Revision$" - -class - CMS_TEMPORAL_USER - -inherit - - CMS_USER - -create - make, - make_with_id - -feature -- Access - - application: detachable STRING_32 - -- User application - -feature -- Element change - - set_application (an_application: like application) - -- Assign `application' with `an_application'. - do - application := an_application - ensure - application_assigned: application = an_application - end - -end diff --git a/modules/auth/persistence/cms_auth_storage_i.e b/modules/auth/persistence/cms_auth_storage_i.e index 48851ad..e6ba77e 100644 --- a/modules/auth/persistence/cms_auth_storage_i.e +++ b/modules/auth/persistence/cms_auth_storage_i.e @@ -58,14 +58,14 @@ feature -- New Temp User deferred end - new_temp_user (a_user: CMS_TEMPORAL_USER) + new_temp_user (a_user: CMS_USER) -- New temp user `a_user'. require no_id: not a_user.has_id deferred end - delete_user (a_user: CMS_TEMPORAL_USER) + delete_user (a_user: CMS_USER) -- Delete user `a_user'. require has_id: a_user.has_id diff --git a/modules/auth/persistence/cms_auth_storage_null.e b/modules/auth/persistence/cms_auth_storage_null.e index 505b558..18abc06 100644 --- a/modules/auth/persistence/cms_auth_storage_null.e +++ b/modules/auth/persistence/cms_auth_storage_null.e @@ -48,12 +48,12 @@ feature -- Temp Users do end - new_temp_user (a_user: CMS_TEMPORAL_USER) + new_temp_user (a_user: CMS_USER) -- do end - delete_user (a_user: CMS_TEMPORAL_USER) + delete_user (a_user: CMS_USER) -- do end diff --git a/modules/auth/persistence/cms_auth_storage_sql.e b/modules/auth/persistence/cms_auth_storage_sql.e index ea2fe44..4707972 100644 --- a/modules/auth/persistence/cms_auth_storage_sql.e +++ b/modules/auth/persistence/cms_auth_storage_sql.e @@ -101,7 +101,7 @@ feature -- Access User Outh feature {NONE} -- Implementation: User - fetch_user: detachable CMS_TEMPORAL_USER + fetch_user: detachable CMS_USER local l_id: INTEGER_64 l_name: detachable READABLE_STRING_32 @@ -125,7 +125,10 @@ feature {NONE} -- Implementation: User if Result /= Void then if attached sql_read_string (3) as l_password then -- FIXME: should we return the password here ??? - Result.set_password (l_password) + Result.set_hashed_password (l_password) + end + if attached sql_read_string (4) as l_salt then + Result.set_email (l_salt) end if attached sql_read_string (5) as l_email then Result.set_email (l_email) @@ -141,7 +144,7 @@ feature {NONE} -- Implementation: User feature -- New Temp User - new_temp_user (a_user: CMS_TEMPORAL_USER) + new_temp_user (a_user: CMS_USER) -- Add a new temp_user `a_user'. local l_parameters: STRING_TABLE [detachable ANY] @@ -200,7 +203,7 @@ feature -- Remove Activation sql_finalize end - delete_user (a_user: CMS_TEMPORAL_USER) + delete_user (a_user: CMS_USER) -- Delete user `a_user'. local l_parameters: STRING_TABLE [detachable ANY] diff --git a/modules/auth/site/scripts/auth_temp_user.tpl b/modules/auth/site/scripts/auth_temp_users.tpl similarity index 78% rename from modules/auth/site/scripts/auth_temp_user.tpl rename to modules/auth/site/scripts/auth_temp_users.tpl index 38ae29b..14d42f6 100644 --- a/modules/auth/site/scripts/auth_temp_user.tpl +++ b/modules/auth/site/scripts/auth_temp_users.tpl @@ -1,6 +1,6 @@ -DROP TABLE IF EXISTS "auth_temp_user"; -CREATE TABLE `auth_temp_user` ( +DROP TABLE IF EXISTS "auth_temp_users"; +CREATE TABLE `auth_temp_users` ( `uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` VARCHAR(100) NOT NULL, `password` VARCHAR(100) NOT NULL, diff --git a/modules/auth/site/templates/block_register.tpl b/modules/auth/site/templates/block_register.tpl index 9e7c478..e55b7b1 100644 --- a/modules/auth/site/templates/block_register.tpl +++ b/modules/auth/site/templates/block_register.tpl @@ -1,7 +1,7 @@

- Register Form + Registration
@@ -20,8 +20,19 @@ {$error_email/}
{/if}
- - +
+ + + {if isset="$error_application"} + {$error_application/}
+ {/if} +
+ {unless isempty="$recaptcha_site_key"} +
+
+ {/unless}
diff --git a/src/persistence/user/cms_user_storage_i.e b/src/persistence/user/cms_user_storage_i.e index 2692e1b..958eca3 100644 --- a/src/persistence/user/cms_user_storage_i.e +++ b/src/persistence/user/cms_user_storage_i.e @@ -104,6 +104,12 @@ feature -- Change: user deferred end + new_user_from_temporal_user (a_user: CMS_USER) + require + no_id: not a_user.has_id + deferred + end + update_user (a_user: CMS_USER) -- Save user `a_user'. require @@ -234,6 +240,6 @@ feature -- Change: User password recovery end note - copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + 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 diff --git a/src/persistence/user/cms_user_storage_null.e b/src/persistence/user/cms_user_storage_null.e index c899696..0af4a9c 100644 --- a/src/persistence/user/cms_user_storage_null.e +++ b/src/persistence/user/cms_user_storage_null.e @@ -65,6 +65,11 @@ feature -- Change: user a_user.set_id (1) end + new_user_from_temporal_user (a_user: CMS_USER) + do + a_user.set_id (1) + end + update_user (a_user: CMS_USER) -- Update user `a_user'. do @@ -149,6 +154,6 @@ feature -- Change: User password recovery end note - copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + 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 diff --git a/src/persistence/user/cms_user_storage_sql_i.e b/src/persistence/user/cms_user_storage_sql_i.e index 640d6ef..16129c0 100644 --- a/src/persistence/user/cms_user_storage_sql_i.e +++ b/src/persistence/user/cms_user_storage_sql_i.e @@ -198,6 +198,45 @@ feature -- Access: user end feature -- Change: user + new_user_from_temporal_user (a_user: CMS_USER) + -- Add a new user `a_user'. + local + l_parameters: STRING_TABLE [detachable ANY] + do + error_handler.reset + if + attached a_user.hashed_password as l_password_hash and then + attached a_user.email as l_email and then + attached a_user.salt as l_password_salt + then + sql_begin_transaction + + write_information_log (generator + ".new_user") + create l_parameters.make (4) + l_parameters.put (a_user.name, "name") + l_parameters.put (l_password_hash, "password") + l_parameters.put (l_password_salt, "salt") + l_parameters.put (l_email, "email") + l_parameters.put (create {DATE_TIME}.make_now_utc, "created") + l_parameters.put (a_user.status, "status") + + sql_insert (sql_insert_user, l_parameters) + if not error_handler.has_error then + a_user.set_id (last_inserted_user_id) + update_user_roles (a_user) + end + if not error_handler.has_error then + sql_commit_transaction + else + sql_rollback_transaction + end + sql_finalize + else + -- set error + error_handler.add_custom_error (-1, "bad request" , "Missing password or email") + end + end + new_user (a_user: CMS_USER) -- Add a new user `a_user'. local @@ -1010,6 +1049,6 @@ feature {NONE} -- User Password Recovery -- Retrieve user by password token if exist. note - copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + 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 diff --git a/src/service/user/cms_user_api.e b/src/service/user/cms_user_api.e index 956afd5..36f1e47 100644 --- a/src/service/user/cms_user_api.e +++ b/src/service/user/cms_user_api.e @@ -251,7 +251,26 @@ feature -- Change User do reset_error if - attached a_user.password as l_password and then + 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 + + new_user_from_temporal_user (a_user: CMS_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 (a_user) @@ -321,6 +340,6 @@ feature -- User status -- The user is trashed (soft delete), ready to be deleted/destroyed from storage. note - copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Eiffel Software and others" + 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