diff --git a/examples/demo/site/config/cms.ini b/examples/demo/site/config/cms.ini index 14ecba6..41b8ec5 100644 --- a/examples/demo/site/config/cms.ini +++ b/examples/demo/site/config/cms.ini @@ -4,13 +4,26 @@ root-dir=site/www #modules-dir=site/modules [site] +# Name of the site, for the title, and eventual message. name=Eiffel CMS -email=your@email.com + +# Email used for notification +email=noreply@example.com + +# Name of website theme. theme=bootstrap +[notification] +# By default, notification.email = site.email +# you can change here the email that will receive internal messages. +#email=notif@example.com + [mailer] +#The mailer is used mostly used by the CMS to send email messages. +# you can change the "From:" by setting mailer.from value" +#from=... #smtp=localhost:25 -#sendmail=/usr/bin/sendmail +#sendmail=site\bin\roc_sendmail.bat output=@stderr [modules] diff --git a/modules/auth/auth-safe.ecf b/modules/auth/auth-safe.ecf index 5824089..c73df30 100644 --- a/modules/auth/auth-safe.ecf +++ b/modules/auth/auth-safe.ecf @@ -22,8 +22,6 @@ - - diff --git a/modules/auth/cms_authentication_email_service.e b/modules/auth/cms_authentication_email_service.e new file mode 100644 index 0000000..c95a1d0 --- /dev/null +++ b/modules/auth/cms_authentication_email_service.e @@ -0,0 +1,150 @@ +note + description: "Summary description for {CMS_AUTHENTICATION_EMAIL_SERVICE}." + date: "$Date$" + revision: "$Revision$" + +class + CMS_AUTHENTICATION_EMAIL_SERVICE + +create + make + +feature {NONE} -- Initialization + + make (a_params: like parameters) + -- Create instance of email service with `a_params' data. + do + parameters := a_params + initialize + end + + initialize + -- Initialize service. + do + create error_handler.make + reset_error + end + +feature -- Access + + parameters: CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS + -- Associated parameters. + + cms_api: CMS_API + do + Result := parameters.cms_api + end + + contact_email_address: IMMUTABLE_STRING_8 + -- contact email. + do + Result := parameters.contact_email_address + end + + notif_email_address: IMMUTABLE_STRING_8 + -- Site admin's email. + do + Result := parameters.notif_email_address + end + + sender_email_address: IMMUTABLE_STRING_8 + -- Site sender's email. + do + Result := parameters.sender_email_address + end + +feature -- Error + + error_handler: ERROR_HANDLER + + has_error: BOOLEAN + do + Result := error_handler.has_error + end + + reset_error + do + error_handler.reset + end + +feature -- Basic Operations / Internal + + send_internal_email (a_content: READABLE_STRING_GENERAL) + do + send_message (sender_email_address, notif_email_address, "Notification Contact", a_content) + end + + send_email_internal_server_error (a_content: READABLE_STRING_GENERAL) + do + send_message (sender_email_address, notif_email_address, "Internal Server Error", a_content) + end + +feature -- Basic Operations / Contact + + send_contact_email (a_to, a_content: READABLE_STRING_8) + -- Send successful contact message `a_token' to `a_to'. + require + attached_to: a_to /= Void + local + l_message: STRING + do + create l_message.make_from_string (parameters.account_activation) + l_message.replace_substring_all ("$link", a_content) + send_message (contact_email_address, a_to, parameters.contact_subject_register, l_message) + end + + send_contact_activation_email (a_to, a_content: READABLE_STRING_8) + -- Send successful contact message `a_token' to `a_to'. + require + attached_to: a_to /= Void + local + l_message: STRING + do + create l_message.make_from_string (parameters.account_re_activation) + l_message.replace_substring_all ("$link", a_content) + send_message (contact_email_address, a_to, parameters.contact_subject_activate, l_message) + end + + send_contact_password_email (a_to, a_content: READABLE_STRING_8) + -- Send successful contact message `a_token' to `a_to'. + require + attached_to: a_to /= Void + local + l_message: STRING + do + create l_message.make_from_string (parameters.account_password) + l_message.replace_substring_all ("$link", a_content) + send_message (contact_email_address, a_to, parameters.contact_subject_password, l_message) + end + + send_contact_welcome_email (a_to, a_content: READABLE_STRING_8) + -- Send successful contact message `a_token' to `a_to'. + require + attached_to: a_to /= Void + local + l_message: STRING + do + create l_message.make_from_string (parameters.account_welcome) + l_message.replace_substring_all ("$link", a_content) + send_message (contact_email_address, a_to, parameters.contact_subject_oauth, l_message) + end + +feature {NONE} -- Implementation + + send_message (a_from_address, a_to_address: READABLE_STRING_8; a_subjet: READABLE_STRING_GENERAL; a_content: READABLE_STRING_GENERAL) + local + l_email: CMS_EMAIL + utf: UTF_CONVERTER + do + reset_error + l_email := cms_api.new_email (a_to_address, utf.escaped_utf_32_string_to_utf_8_string_8 (a_subjet), utf.escaped_utf_32_string_to_utf_8_string_8 (a_content)) + l_email.set_from_address (a_from_address) + l_email.add_header_line ("MIME-Version:1.0") + l_email.add_header_line ("Content-Type: text/html; charset=utf-8") + cms_api.process_email (l_email) + if cms_api.has_error then + error_handler.add_custom_error (-1, generator + "send_message failed", cms_api.string_representation_of_errors) + end + end + +end diff --git a/modules/auth/cms_authentication_email_service_parameters.e b/modules/auth/cms_authentication_email_service_parameters.e index efb7b2a..51ce516 100644 --- a/modules/auth/cms_authentication_email_service_parameters.e +++ b/modules/auth/cms_authentication_email_service_parameters.e @@ -6,9 +6,6 @@ note class CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS -inherit - EMAIL_SERVICE_PARAMETERS - create make @@ -23,19 +20,15 @@ feature {NONE} -- Initialization do cms_api := a_cms_api -- Use global smtp setting if any, otherwise "localhost" - smtp_server := utf.escaped_utf_32_string_to_utf_8_string_8 (a_cms_api.setup.text_item_or_default ("smtp", "localhost")) l_site_name := utf.escaped_utf_32_string_to_utf_8_string_8 (a_cms_api.setup.site_name) - admin_email := a_cms_api.setup.site_email + notif_email_address := a_cms_api.setup.site_notification_email + sender_email_address := a_cms_api.setup.site_email - if not admin_email.has ('<') then - admin_email := l_site_name + " <" + admin_email +">" + if not notif_email_address.has ('<') then + notif_email_address := l_site_name + " <" + notif_email_address + ">" end - if attached {CONFIG_READER} a_cms_api.module_configuration_by_name ({CMS_AUTHENTICATION_MODULE}.name, Void) as cfg then - if attached cfg.text_item ("smtp") as l_smtp then - -- Overwrite global smtp setting if any. - smtp_server := utf.utf_32_string_to_utf_8_string_8 (l_smtp) - end + if attached a_cms_api.module_configuration_by_name ({CMS_AUTHENTICATION_MODULE}.name, Void) as cfg then s := cfg.text_item ("email") if s /= Void then l_contact_email := utf.utf_32_string_to_utf_8_string_8 (s) @@ -56,15 +49,14 @@ feature {NONE} -- Initialization if s /= Void then l_subject_oauth := utf.utf_32_string_to_utf_8_string_8 (s) end - end if l_contact_email /= Void then if not l_contact_email.has ('<') then l_contact_email := l_site_name + " <" + l_contact_email + ">" end - contact_email := l_contact_email + contact_email_address := l_contact_email else - contact_email := admin_email + contact_email_address := notif_email_address end if l_subject_register /= Void then contact_subject_register := l_subject_register @@ -87,18 +79,17 @@ feature {NONE} -- Initialization else contact_subject_oauth := "Welcome." end - end feature -- Access cms_api: CMS_API - smtp_server: IMMUTABLE_STRING_8 + notif_email_address: IMMUTABLE_STRING_8 - admin_email: IMMUTABLE_STRING_8 + sender_email_address: IMMUTABLE_STRING_8 - contact_email: IMMUTABLE_STRING_8 + contact_email_address: IMMUTABLE_STRING_8 -- Contact email. contact_subject_register: IMMUTABLE_STRING_8 diff --git a/modules/auth/cms_authentication_module.e b/modules/auth/cms_authentication_module.e index 3787b75..a858425 100644 --- a/modules/auth/cms_authentication_module.e +++ b/modules/auth/cms_authentication_module.e @@ -184,7 +184,7 @@ feature -- Handler l_user_api: CMS_USER_API u: CMS_USER l_exist: BOOLEAN - es: CMS_AUTHENTICATON_EMAIL_SERVICE + es: CMS_AUTHENTICATION_EMAIL_SERVICE l_url: STRING l_token: STRING do @@ -273,7 +273,7 @@ feature -- Handler handle_reactivation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) local r: CMS_RESPONSE - es: CMS_AUTHENTICATON_EMAIL_SERVICE + es: CMS_AUTHENTICATION_EMAIL_SERVICE l_user_api: CMS_USER_API l_token: STRING l_url: STRING @@ -313,7 +313,7 @@ feature -- Handler handle_new_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) local r: CMS_RESPONSE - es: CMS_AUTHENTICATON_EMAIL_SERVICE + es: CMS_AUTHENTICATION_EMAIL_SERVICE l_user_api: CMS_USER_API l_token: STRING l_url: STRING diff --git a/modules/auth/cms_authenticaton_email_service.e b/modules/auth/cms_authenticaton_email_service.e deleted file mode 100644 index d4a1984..0000000 --- a/modules/auth/cms_authenticaton_email_service.e +++ /dev/null @@ -1,88 +0,0 @@ -note - description: "Summary description for {CMS_AUTHENTICATON_EMAIL_SERVICE}." - date: "$Date$" - revision: "$Revision$" - -class - CMS_AUTHENTICATON_EMAIL_SERVICE - -inherit - EMAIL_SERVICE - redefine - initialize, - parameters - end - -create - make - -feature {NONE} -- Initialization - - initialize - do - Precursor - contact_email := parameters.contact_email - end - - parameters: CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS - -- Associated parameters. - -feature -- Access - - contact_email: IMMUTABLE_STRING_8 - -- contact email. - -feature -- Basic Operations - - send_contact_email (a_to, a_content: READABLE_STRING_8) - -- Send successful contact message `a_token' to `a_to'. - require - attached_to: a_to /= Void - local - l_message: STRING - do - create l_message.make_from_string (parameters.account_activation) - l_message.replace_substring_all ("$link", a_content) - send_message (contact_email, a_to, parameters.contact_subject_register, l_message) - end - - - send_contact_activation_email (a_to, a_content: READABLE_STRING_8) - -- Send successful contact message `a_token' to `a_to'. - require - attached_to: a_to /= Void - local - l_message: STRING - do - create l_message.make_from_string (parameters.account_re_activation) - l_message.replace_substring_all ("$link", a_content) - send_message (contact_email, a_to, parameters.contact_subject_activate, l_message) - end - - - send_contact_password_email (a_to, a_content: READABLE_STRING_8) - -- Send successful contact message `a_token' to `a_to'. - require - attached_to: a_to /= Void - local - l_message: STRING - do - create l_message.make_from_string (parameters.account_password) - l_message.replace_substring_all ("$link", a_content) - send_message (contact_email, a_to, parameters.contact_subject_password, l_message) - end - - send_contact_welcome_email (a_to, a_content: READABLE_STRING_8) - -- Send successful contact message `a_token' to `a_to'. - require - attached_to: a_to /= Void - local - l_message: STRING - do - create l_message.make_from_string (parameters.account_welcome) - l_message.replace_substring_all ("$link", a_content) - send_message (contact_email, a_to, parameters.contact_subject_oauth, l_message) - end - - -end diff --git a/modules/oauth20/cms_oauth_20_module.e b/modules/oauth20/cms_oauth_20_module.e index 7cf6bab..982d3e3 100644 --- a/modules/oauth20/cms_oauth_20_module.e +++ b/modules/oauth20/cms_oauth_20_module.e @@ -430,7 +430,7 @@ feature -- OAuth2 Login with Provider l_user: CMS_USER l_roles: LIST [CMS_USER_ROLE] l_cookie: WSF_COOKIE - es: CMS_AUTHENTICATON_EMAIL_SERVICE + es: CMS_AUTHENTICATION_EMAIL_SERVICE do if attached {WSF_STRING} req.path_parameter ({CMS_OAUTH_20_CONSTANTS}.oauth_callback) as l_callback and then attached {CMS_OAUTH_20_CONSUMER} a_user_oauth_api.oauth_consumer_by_callback (l_callback.value) as l_consumer and then diff --git a/modules/openid/cms_openid_module.e b/modules/openid/cms_openid_module.e index cc84735..959e606 100644 --- a/modules/openid/cms_openid_module.e +++ b/modules/openid/cms_openid_module.e @@ -390,7 +390,7 @@ feature -- Openid Login l_user: CMS_USER l_roles: LIST [CMS_USER_ROLE] l_cookie: WSF_COOKIE - es: CMS_AUTHENTICATON_EMAIL_SERVICE + es: CMS_AUTHENTICATION_EMAIL_SERVICE b: STRING o: OPENID_CONSUMER v: OPENID_CONSUMER_VALIDATION diff --git a/src/configuration/cms_setup.e b/src/configuration/cms_setup.e index 93e3602..baf3a97 100644 --- a/src/configuration/cms_setup.e +++ b/src/configuration/cms_setup.e @@ -16,11 +16,12 @@ feature {NONE} -- Initialization initialize local l_url: like site_url + l_email: detachable READABLE_STRING_8 do site_location := environment.path --| Site id, used to identified a site, this could be set to a uuid, or else - site_id := text_item_or_default ("site.id", "_EWF_CMS_NO_ID_") + site_id := string_8_item_or_default ("site.id", "_ROC_CMS_NO_ID_") -- Site url: optional, but ending with a slash l_url := string_8_item ("site_url") @@ -32,11 +33,26 @@ feature {NONE} -- Initialization site_url := l_url -- Site name - site_name := text_item_or_default ("site.name", "EWF::CMS") + site_name := text_item_or_default ("site.name", "Another Eiffel ROC Website") - -- Site email for any internal notification - -- Can be also used to precise the "From:" value for email. - site_email := text_item_or_default ("site.email", "webmaster") + -- Website email used to send email. + -- used as real "From:" email. + -- Any "From:" header passed to the CMS email sender will appear as "Reply-To:" + -- or ignored if a reply-to header is already set. + l_email := string_8_item ("site.email") + if l_email = Void then + -- FIXME: find better default value! + -- Or handler configuration error (missing value)!!! + l_email := string_8_item_or_default ("mailer.from", "webmaster") + end + if l_email.has ('<') then + l_email := site_name + " <" + l_email + ">" + end + site_email := l_email + + -- Email address for current web site + --| Also known + site_notification_email := string_8_item_or_default ("notification.email", site_email) -- Location for public files @@ -181,8 +197,12 @@ feature -- Access: Site -- Name of the site. site_email: READABLE_STRING_8 - -- Admin email address for the site. - -- Mainly used for internal notification. + -- Website email address. + -- Used as "From:" address when the site is sending emails + -- cf: `CMS_SETUP.mailer'. + + site_notification_email: READABLE_STRING_8 + -- Email address receiving internal notification. site_url: detachable READABLE_STRING_8 -- Optional url of current CMS site. @@ -223,6 +243,16 @@ feature -- Query deferred end + string_8_item_or_default (a_name: READABLE_STRING_GENERAL; a_default_value: READABLE_STRING_8): READABLE_STRING_8 + -- `string_8_item' associated with `a_name' or if none, `a_default_value'. + do + if attached string_8_item (a_name) as v then + Result := v + else + Result := a_default_value + end + end + feature -- Access: Theme site_location: PATH @@ -333,6 +363,6 @@ feature -- Element change 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/service/cms_api.e b/src/service/cms_api.e index ce43c95..5fd32d5 100644 --- a/src/service/cms_api.e +++ b/src/service/cms_api.e @@ -323,7 +323,9 @@ feature -- Emails process_email (e: CMS_EMAIL) -- Process email `e'. do + log ("mailer", "Send email %"" + e.subject + "%"%N" + e.header, {CMS_LOG}.level_notice, Void) reset_error + prepare_email (e) setup.mailer.safe_process_email (e) if setup.mailer.has_error then error_handler.add_custom_error (0, "Mailer error", "Error occurred while processing email.") @@ -333,10 +335,33 @@ feature -- Emails process_emails (lst: ITERABLE [CMS_EMAIL]) -- Process collection of email `lst'. do - reset_error - setup.mailer.process_emails (lst) - if setup.mailer.has_error then - error_handler.add_custom_error (0, "Mailer error", "Error occurred while processing emails.") + across + lst as ic + loop + process_email (ic.item) + end + end + +feature {NONE} -- Emails implementation + + prepare_email (e: CMS_EMAIL) + -- Prepare email `e', and update parameters if needed. + local + l_sender, l_from: READABLE_STRING_8 + do + l_sender := setup.site_email + l_from := e.from_address + if not l_sender.is_case_insensitive_equal_general (l_from) then + e.set_from_address (l_sender) + if not e.has_header ("Return-Path") then + e.add_header_line ("Return-path: " + l_from) + end + if e.reply_to_address = Void then + e.set_reply_to_address (l_from) + else + --| As a Reply-To address is already set, + --| ignore previous from address. + end end end @@ -548,7 +573,7 @@ feature -- Element Change: Error error_handler.reset end -feature {NONE}-- Implemenation +feature {NONE}-- Implementation error_handler: ERROR_HANDLER -- Error handler. @@ -834,7 +859,7 @@ feature -- Hook 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