diff --git a/examples/demo/site/modules/auth/files/js/roc_auth.js b/examples/demo/site/modules/auth/files/js/roc_auth.js new file mode 100644 index 0000000..e4b499a --- /dev/null +++ b/examples/demo/site/modules/auth/files/js/roc_auth.js @@ -0,0 +1,323 @@ +var ROC_AUTH = ROC_AUTH || { }; + +var loginURL = "/basic_auth_login"; +var logoutURL = "/basic_auth_logoff"; + +var userAgent = navigator.userAgent.toLowerCase(); +var firstLogIn = true; + +ROC_AUTH.login = function() { + var form = document.forms[0]; + var username = form.username.value; + var password = form.password.value; + //var host = form.host.value; + var origin = window.location.origin.concat(window.location.pathname); + var _login = function(){ + + + if (document.getElementById('myModalFormId') !== null ) { + ROC_AUTH.remove ('myModalFormId'); + } + + + if (username === "" || password === "") { + if (document.getElementById('myModalFormId') === null ) { + var newdiv = document.createElement('div'); + newdiv.innerHTML = "
Invalid Credentials
"; + newdiv.id = 'myModalFormId'; + $("body").append(newdiv); + } + }else{ + + //Instantiate HTTP Request + var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP")); + request.open("GET", loginURL, true, username, password); + request.send(null); + + //Process Response + request.onreadystatechange = function(){ + if (request.readyState == 4) { + if (request.status==200) { + delete form; + window.location=window.location.origin; + } + else{ + if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){ + } + + if (document.getElementById('myModalFormId') === null ) { + var newdiv = document.createElement('div'); + newdiv.innerHTML = "
Invalid Credentials
"; + newdiv.id = 'myModalFormId'; + $("body").append(newdiv); + } + + } + } + } + } + } + + var userAgent = navigator.userAgent.toLowerCase(); + if (userAgent.indexOf("firefox") != -1){ //TODO: check version number + if (firstLogIn) _login(); + else logoff(_login); + } + else{ + _login(); + } + + if (firstLogIn) firstLogIn = false; +}; + + +ROC_AUTH.login_with_redirect = function() { + var form = document.forms[2]; + var username = form.username.value; + var password = form.password.value; + var host = form.host.value; + var _login = function(){ + + var redirectURL = form.redirect && form.redirect.value || ""; + + + $("#imgProgressRedirect").show(); + + if (document.getElementById('myModalFormId') !== null ) { + ROC_AUTH.remove ('myModalFormId'); + } + + + if (username === "" || password === "") { + if (document.getElementById('myModalFormId') === null ) { + var newdiv = document.createElement('div'); + newdiv.innerHTML = "
Invalid Credentials
"; + newdiv.id = 'myModalFormId'; + $("body").append(newdiv); + $("#imgProgressRedirect").hide(); + } + }else{ + + //Instantiate HTTP Request + var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP")); + request.open("GET", host.concat(loginURL), true, username, password); + request.send(null); + + //Process Response + request.onreadystatechange = function(){ + if (request.readyState == 4) { + if (request.status==200) { + if (redirectURL === "") { + window.location=host.concat("/"); + } else { + window.location=host.concat(redirectURL); + } + + } + else{ + if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){ + } + + if (document.getElementById('myModalFormId') === null ) { + var newdiv = document.createElement('div'); + newdiv.innerHTML = "
Invalid Credentials
"; + newdiv.id = 'myModalFormId'; + $("body").append(newdiv); + $("#imgProgressRedirect").hide(); + } + + } + } + } + } + } + + var userAgent = navigator.userAgent.toLowerCase(); + if (userAgent.indexOf("firefox") != -1){ //TODO: check version number + if (firstLogIn) _login(); + else logoff(_login); + } + else{ + _login(); + } + + if (firstLogIn) firstLogIn = false; +}; + + +ROC_AUTH.getQueryParameterByName = function (name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), + results = regex.exec(location.search); + return results === null ? " " : decodeURIComponent(results[1].replace(/\+/g, " ")); +} + +ROC_AUTH.logoff = function(callback){ + var form = document.forms[0]; + var host = form.host.value; + + if (userAgent.indexOf("msie") != -1) { + document.execCommand("ClearAuthenticationCache"); + } + else if (userAgent.indexOf("firefox") != -1){ //TODO: check version number + + var request1 = new XMLHttpRequest(); + var request2 = new XMLHttpRequest(); + + //Logout. Tell the server not to return the "WWW-Authenticate" header + request1.open("GET", host.concat(logoutURL) + "?prompt=false", true); + request1.send(""); + request1.onreadystatechange = function(){ + if (request1.readyState == 4) { + + //Sign in with dummy credentials to clear the auth cache + request2.open("GET", host.concat(logoutURL), true, "logout", "logout"); + request2.send(""); + + request2.onreadystatechange = function(){ + if (request2.readyState == 4) { + if (callback!=null) { callback.call(); } else { window.location=host.concat(logoutURL);} + } + } + + } + } + } + else { + var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP")); + request.open("GET", host.concat(logoutURL), true, "logout", "logout"); + request.send(""); + request.onreadystatechange = function(){ + if (request.status==401 || request.status==403 ) { window.location=host.concat(logoutURL); + } + } + } +}; + + +ROC_AUTH.remove = function (id) +{ + var element = document.getElementById(id); + element.outerHTML = ""; + delete element; + return; +}; + + + +$(document).ready(function() { + + if (typeof String.prototype.contains != 'function') { + String.prototype.contains = function (str){ + return this.indexOf(str) != -1; + }; + } + ROC_AUTH.progressive_loging(); + +}); + + +ROC_AUTH.progressive_loging = function () { + + ROC_AUTH.login_href(); +}; + + +$(document).keypress(function(e) { + if ((e.which === 13) && (e.target.localName === 'input' && e.target.id === 'password')) { + ROC_AUTH.login(); + } +}); + +ROC_AUTH.OnOneClick = function(event) { + event.preventDefault(); + if ( document.forms[0] === undefined ) { + ROC_AUTH.create_form(); + } + return false; +}; + +ROC_AUTH.login_href = function() { + var els = document.getElementsByTagName("a"); + for (var i = 0, l = els.length; i < l; i++) { + var el = els[i]; + if (el.href.contains("/basic_auth_login?destination")) { + loginURL = el.href; + var OneClick = el; + OneClick.addEventListener('click', ROC_AUTH.OnOneClick, false); + } + } +}; + + +ROC_AUTH.create_form = function() { + + // Fetching HTML Elements in Variables by ID. + var createform = document.createElement('form'); // Create New Element Form + createform.setAttribute("action", ""); // Setting Action Attribute on Form + createform.setAttribute("method", "post"); // Setting Method Attribute on Form + $("body").append(createform); + + var heading = document.createElement('h2'); // Heading of Form + heading.innerHTML = "Login Form "; + createform.appendChild(heading); + + var line = document.createElement('hr'); // Giving Horizontal Row After Heading + createform.appendChild(line); + + var linebreak = document.createElement('br'); + createform.appendChild(linebreak); + + var namelabel = document.createElement('label'); // Create Label for Name Field + namelabel.innerHTML = "Username : "; // Set Field Labels + createform.appendChild(namelabel); + + var inputelement = document.createElement('input'); // Create Input Field for UserName + inputelement.setAttribute("type", "text"); + inputelement.setAttribute("name", "username"); + inputelement.setAttribute("required","required"); + createform.appendChild(inputelement); + + var linebreak = document.createElement('br'); + createform.appendChild(linebreak); + + var passwordlabel = document.createElement('label'); // Create Label for Password Field + passwordlabel.innerHTML = "Password : "; + createform.appendChild(passwordlabel); + + var passwordelement = document.createElement('input'); // Create Input Field for Password. + passwordelement.setAttribute("type", "password"); + passwordelement.setAttribute("name", "password"); + passwordelement.setAttribute("id", "password"); + passwordelement.setAttribute("required","required"); + createform.appendChild(passwordelement); + + + var passwordbreak = document.createElement('br'); + createform.appendChild(passwordbreak); + + + var submitelement = document.createElement('button'); // Append Submit Button + submitelement.setAttribute("type", "button"); + submitelement.setAttribute("onclick", "ROC_AUTH.login();"); + submitelement.innerHTML = "Sign In "; + createform.appendChild(submitelement); + +}; + + +var password = document.getElementById("password") + , confirm_password = document.getElementById("confirm_password"); + +ROC_AUTH.validatePassword =function(){ + if ((password != null) && (confirm_password != null)){ + if(password.value != confirm_password.value) { + confirm_password.setCustomValidity("Passwords Don't Match"); + } else { + confirm_password.setCustomValidity(''); + } + } +} + +password.onchange = ROC_AUTH.validatePassword(); +confirm_password.onkeyup = ROC_AUTH.validatePassword; \ No newline at end of file diff --git a/examples/demo/site/modules/auth/templates/block_login.tpl b/examples/demo/site/modules/auth/templates/block_login.tpl new file mode 100644 index 0000000..0549b24 --- /dev/null +++ b/examples/demo/site/modules/auth/templates/block_login.tpl @@ -0,0 +1,34 @@ +
+ {unless isset="$user"} +

Login or Register

+
+
+
+
+ + +
+ +
+ + +
+ + +
+
+
+
+
+

+ Forgot password? +

+
+
+
+ {foreach item="item" from="$oauth_consumers"} + Login with {$item/}
+ {/foreach} +
+ {/unless} +
diff --git a/examples/demo/site/modules/basic_auth/templates/block_new_password.tpl b/examples/demo/site/modules/auth/templates/block_new_password.tpl similarity index 100% rename from examples/demo/site/modules/basic_auth/templates/block_new_password.tpl rename to examples/demo/site/modules/auth/templates/block_new_password.tpl diff --git a/examples/demo/site/modules/basic_auth/templates/block_post_password.tpl b/examples/demo/site/modules/auth/templates/block_post_password.tpl similarity index 100% rename from examples/demo/site/modules/basic_auth/templates/block_post_password.tpl rename to examples/demo/site/modules/auth/templates/block_post_password.tpl diff --git a/examples/demo/site/modules/basic_auth/templates/block_post_reactivate.tpl b/examples/demo/site/modules/auth/templates/block_post_reactivate.tpl similarity index 100% rename from examples/demo/site/modules/basic_auth/templates/block_post_reactivate.tpl rename to examples/demo/site/modules/auth/templates/block_post_reactivate.tpl diff --git a/examples/demo/site/modules/basic_auth/templates/block_post_register.tpl b/examples/demo/site/modules/auth/templates/block_post_register.tpl similarity index 100% rename from examples/demo/site/modules/basic_auth/templates/block_post_register.tpl rename to examples/demo/site/modules/auth/templates/block_post_register.tpl diff --git a/examples/demo/site/modules/basic_auth/templates/block_post_reset.tpl b/examples/demo/site/modules/auth/templates/block_post_reset.tpl similarity index 100% rename from examples/demo/site/modules/basic_auth/templates/block_post_reset.tpl rename to examples/demo/site/modules/auth/templates/block_post_reset.tpl diff --git a/examples/demo/site/modules/basic_auth/templates/block_reactivate.tpl b/examples/demo/site/modules/auth/templates/block_reactivate.tpl similarity index 100% rename from examples/demo/site/modules/basic_auth/templates/block_reactivate.tpl rename to examples/demo/site/modules/auth/templates/block_reactivate.tpl diff --git a/examples/demo/site/modules/basic_auth/templates/block_register.tpl b/examples/demo/site/modules/auth/templates/block_register.tpl similarity index 100% rename from examples/demo/site/modules/basic_auth/templates/block_register.tpl rename to examples/demo/site/modules/auth/templates/block_register.tpl diff --git a/examples/demo/site/modules/basic_auth/templates/block_reset_password.tpl b/examples/demo/site/modules/auth/templates/block_reset_password.tpl similarity index 100% rename from examples/demo/site/modules/basic_auth/templates/block_reset_password.tpl rename to examples/demo/site/modules/auth/templates/block_reset_password.tpl diff --git a/examples/demo/site/modules/basic_auth/files/js/roc_auth.js b/examples/demo/site/modules/basic_auth/files/js/roc_auth.js index e4b499a..75382ef 100644 --- a/examples/demo/site/modules/basic_auth/files/js/roc_auth.js +++ b/examples/demo/site/modules/basic_auth/files/js/roc_auth.js @@ -39,7 +39,7 @@ ROC_AUTH.login = function() { if (request.readyState == 4) { if (request.status==200) { delete form; - window.location=window.location.origin; + window.location=origin; } else{ if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){ @@ -310,12 +310,10 @@ var password = document.getElementById("password") , confirm_password = document.getElementById("confirm_password"); ROC_AUTH.validatePassword =function(){ - if ((password != null) && (confirm_password != null)){ - if(password.value != confirm_password.value) { - confirm_password.setCustomValidity("Passwords Don't Match"); - } else { - confirm_password.setCustomValidity(''); - } + if(password.value != confirm_password.value) { + confirm_password.setCustomValidity("Passwords Don't Match"); + } else { + confirm_password.setCustomValidity(''); } } diff --git a/modules/auth/cms_authentication_module.e b/modules/auth/cms_authentication_module.e index c40ce46..8336301 100644 --- a/modules/auth/cms_authentication_module.e +++ b/modules/auth/cms_authentication_module.e @@ -15,6 +15,10 @@ inherit CMS_HOOK_AUTO_REGISTER + CMS_HOOK_VALUE_TABLE_ALTER + + CMS_HOOK_BLOCK + CMS_HOOK_MENU_SYSTEM_ALTER SHARED_EXECUTION_ENVIRONMENT @@ -75,6 +79,12 @@ feature -- Router do 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/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) + end feature -- Hooks configuration @@ -83,8 +93,19 @@ feature -- Hooks configuration -- Module hooks configuration. do auto_subscribe_to_hooks (a_response) + a_response.subscribe_to_block_hook (Current) + a_response.subscribe_to_value_table_alter_hook (Current) end + value_table_alter (a_value: CMS_VALUE_TABLE; a_response: CMS_RESPONSE) + -- + do + if attached current_user (a_response.request) as l_user then + a_value.force (l_user, "user") + end + end + + menu_system_alter (a_menu_system: CMS_MENU_SYSTEM; a_response: CMS_RESPONSE) -- Hook execution on collection of menu contained by `a_menu_system' -- for related response `a_response'. @@ -131,6 +152,462 @@ feature -- Handler + handle_register (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) + local + r: CMS_RESPONSE + l_user_api: CMS_USER_API + u: CMS_USER + l_roles: LIST [CMS_USER_ROLE] + l_exist: BOOLEAN + es: CMS_AUTHENTICATON_EMAIL_SERVICE + l_url: STRING + l_token: STRING + do + create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) + r.set_value ("Register", "optional_content_type") + 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 + then + l_user_api := api.user_api + + if attached l_user_api.user_by_name (l_name.value) then + -- Username already exist. + r.values.force ("The user name exist!", "error_name") + l_exist := True + end + if attached l_user_api.user_by_email (l_email.value) then + -- Emails already exist. + r.values.force ("The email exist!", "error_email") + l_exist := True + end + + if not l_exist then + -- New user + create {ARRAYED_LIST [CMS_USER_ROLE]}l_roles.make (1) + l_roles.force (l_user_api.authenticated_user_role) + + create u.make (l_name.value) + u.set_email (l_email.value) + u.set_password (l_password.value) + u.set_roles (l_roles) + l_user_api.new_user (u) + + -- Create activation token + l_token := new_token + l_user_api.new_activation (l_token, u.id) + l_url := req.absolute_script_url ("/account/activate/" + l_token) + + -- Send Email + create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) + write_debug_log (generator + ".handle register: send_contact_email") + es.send_contact_email (l_email.value, l_url) + + else + r.values.force (l_name.value, "name") + r.values.force (l_email.value, "email") + r.set_status_code ({HTTP_CONSTANTS}.bad_request) + end + end + end + + r.execute + end + + handle_activation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) + local + r: CMS_RESPONSE + l_user_api: CMS_USER_API + l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE + do + 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 attached {CMS_USER} l_user_api.user_by_activation_token (l_token.value) as l_user then + -- Valid user_id + l_user.mark_active + l_user_api.update_user (l_user) + l_user_api.remove_activation (l_token.value) + r.set_value ("Account activated", "optional_content_type") + r.set_main_content ("

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

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

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

") + end + r.execute + else + create l_ir.make (req, res, api) + l_ir.execute + end + end + + + handle_reactivation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) + local + r: CMS_RESPONSE + es: CMS_AUTHENTICATON_EMAIL_SERVICE + l_user_api: CMS_USER_API + l_token: STRING + l_url: STRING + do + 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_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 l_user.is_active then + r.values.force ("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 := req.absolute_script_url ("/account/activate/" + l_token) + + -- Send Email + create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) + write_debug_log (generator + ".handle register: send_contact_activation_email") + es.send_contact_activation_email (l_email.value, l_url) + end + else + r.values.force ("The email does not exist or !", "error_email") + r.values.force (l_email.value, "email") + r.set_status_code ({HTTP_CONSTANTS}.bad_request) + end + end + end + + r.execute + end + + handle_new_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) + local + r: CMS_RESPONSE + es: CMS_AUTHENTICATON_EMAIL_SERVICE + l_user_api: CMS_USER_API + l_token: STRING + l_url: STRING + do + create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) + 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. + 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 + 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) + else + r.values.force ("The email does not exist !", "error_email") + r.values.force (l_email.value, "email") + r.set_status_code ({HTTP_CONSTANTS}.bad_request) + end + end + end + r.execute + end + + + handle_reset_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) + local + r: CMS_RESPONSE + l_user_api: CMS_USER_API + 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 + r.values.force (l_token.value, "token") + if l_user_api.user_by_password_token (l_token.value) = Void then + r.values.force ("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 l_password.value.same_string (l_confirm_password.value) then + -- 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) + l_user_api.remove_password (l_token.value) + end + else + r.values.force ("Passwords Don't Match", "error_password") + r.values.force (l_token.value, "token") + r.set_status_code ({HTTP_CONSTANTS}.bad_request) + end + end + end + r.execute + end + + block_list: ITERABLE [like {CMS_BLOCK}.name] + local + l_string: STRING + do + Result := <<"register", "reactivate", "new_password", "reset_password">> + debug ("roc") + create l_string.make_empty + across + Result as ic + loop + l_string.append (ic.item) + l_string.append_character (' ') + end + 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 + 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 + 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 + 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 + get_block_view_reset_password (a_block_id, a_response) + end + end + + +feature {NONE} -- Token Generation + + new_token: STRING + -- Generate a new token activation token + local + l_token: STRING + l_security: SECURITY_PROVIDER + l_encode: URL_ENCODER + do + 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. + l_token := l_security.token + end + Result := l_token + end + +feature {NONE} -- Helpers + + template_block (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE): detachable CMS_SMARTY_TEMPLATE_BLOCK + -- Smarty content block for `a_block_id' + local + p: detachable PATH + 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 + create Result.make (a_block_id, Void, p.parent, e) + else + create Result.make (a_block_id, Void, p.parent, p) + end + end + end + +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.add_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.request.is_get_request_method then + if attached template_block (a_block_id, a_response) as l_tpl_block then + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + 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") + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + else + if attached template_block ("post_register", a_response) as l_tpl_block then + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + end + end + end + + + get_block_view_reactivate (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) + do + if a_response.request.is_get_request_method then + if attached template_block (a_block_id, a_response) as l_tpl_block then + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + 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") + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + else + if attached template_block ("post_reactivate", a_response) as l_tpl_block then + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + end + end + end + + get_block_view_new_password (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) + do + if a_response.request.is_get_request_method then + if attached template_block (a_block_id, a_response) as l_tpl_block then + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + elseif a_response.request.is_post_request_method then + if 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_email"), "error_email") + l_tpl_block.set_value (a_response.values.item ("email"), "email") + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + else + if attached template_block ("post_password", a_response) as l_tpl_block then + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + end + end + end + + get_block_view_reset_password (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) + 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") + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + 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 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") + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + else + if attached template_block ("post_reset", a_response) as l_tpl_block then + a_response.add_block (l_tpl_block, "content") + else + debug ("cms") + a_response.add_warning_message ("Error with block [" + a_block_id + "]") + end + end + end + end + end + + + note diff --git a/modules/auth/site/files/js/roc_auth.js b/modules/auth/site/files/js/roc_auth.js new file mode 100644 index 0000000..75382ef --- /dev/null +++ b/modules/auth/site/files/js/roc_auth.js @@ -0,0 +1,321 @@ +var ROC_AUTH = ROC_AUTH || { }; + +var loginURL = "/basic_auth_login"; +var logoutURL = "/basic_auth_logoff"; + +var userAgent = navigator.userAgent.toLowerCase(); +var firstLogIn = true; + +ROC_AUTH.login = function() { + var form = document.forms[0]; + var username = form.username.value; + var password = form.password.value; + //var host = form.host.value; + var origin = window.location.origin.concat(window.location.pathname); + var _login = function(){ + + + if (document.getElementById('myModalFormId') !== null ) { + ROC_AUTH.remove ('myModalFormId'); + } + + + if (username === "" || password === "") { + if (document.getElementById('myModalFormId') === null ) { + var newdiv = document.createElement('div'); + newdiv.innerHTML = "
Invalid Credentials
"; + newdiv.id = 'myModalFormId'; + $("body").append(newdiv); + } + }else{ + + //Instantiate HTTP Request + var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP")); + request.open("GET", loginURL, true, username, password); + request.send(null); + + //Process Response + request.onreadystatechange = function(){ + if (request.readyState == 4) { + if (request.status==200) { + delete form; + window.location=origin; + } + else{ + if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){ + } + + if (document.getElementById('myModalFormId') === null ) { + var newdiv = document.createElement('div'); + newdiv.innerHTML = "
Invalid Credentials
"; + newdiv.id = 'myModalFormId'; + $("body").append(newdiv); + } + + } + } + } + } + } + + var userAgent = navigator.userAgent.toLowerCase(); + if (userAgent.indexOf("firefox") != -1){ //TODO: check version number + if (firstLogIn) _login(); + else logoff(_login); + } + else{ + _login(); + } + + if (firstLogIn) firstLogIn = false; +}; + + +ROC_AUTH.login_with_redirect = function() { + var form = document.forms[2]; + var username = form.username.value; + var password = form.password.value; + var host = form.host.value; + var _login = function(){ + + var redirectURL = form.redirect && form.redirect.value || ""; + + + $("#imgProgressRedirect").show(); + + if (document.getElementById('myModalFormId') !== null ) { + ROC_AUTH.remove ('myModalFormId'); + } + + + if (username === "" || password === "") { + if (document.getElementById('myModalFormId') === null ) { + var newdiv = document.createElement('div'); + newdiv.innerHTML = "
Invalid Credentials
"; + newdiv.id = 'myModalFormId'; + $("body").append(newdiv); + $("#imgProgressRedirect").hide(); + } + }else{ + + //Instantiate HTTP Request + var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP")); + request.open("GET", host.concat(loginURL), true, username, password); + request.send(null); + + //Process Response + request.onreadystatechange = function(){ + if (request.readyState == 4) { + if (request.status==200) { + if (redirectURL === "") { + window.location=host.concat("/"); + } else { + window.location=host.concat(redirectURL); + } + + } + else{ + if (navigator.userAgent.toLowerCase().indexOf("firefox") != -1){ + } + + if (document.getElementById('myModalFormId') === null ) { + var newdiv = document.createElement('div'); + newdiv.innerHTML = "
Invalid Credentials
"; + newdiv.id = 'myModalFormId'; + $("body").append(newdiv); + $("#imgProgressRedirect").hide(); + } + + } + } + } + } + } + + var userAgent = navigator.userAgent.toLowerCase(); + if (userAgent.indexOf("firefox") != -1){ //TODO: check version number + if (firstLogIn) _login(); + else logoff(_login); + } + else{ + _login(); + } + + if (firstLogIn) firstLogIn = false; +}; + + +ROC_AUTH.getQueryParameterByName = function (name) { + name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); + var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), + results = regex.exec(location.search); + return results === null ? " " : decodeURIComponent(results[1].replace(/\+/g, " ")); +} + +ROC_AUTH.logoff = function(callback){ + var form = document.forms[0]; + var host = form.host.value; + + if (userAgent.indexOf("msie") != -1) { + document.execCommand("ClearAuthenticationCache"); + } + else if (userAgent.indexOf("firefox") != -1){ //TODO: check version number + + var request1 = new XMLHttpRequest(); + var request2 = new XMLHttpRequest(); + + //Logout. Tell the server not to return the "WWW-Authenticate" header + request1.open("GET", host.concat(logoutURL) + "?prompt=false", true); + request1.send(""); + request1.onreadystatechange = function(){ + if (request1.readyState == 4) { + + //Sign in with dummy credentials to clear the auth cache + request2.open("GET", host.concat(logoutURL), true, "logout", "logout"); + request2.send(""); + + request2.onreadystatechange = function(){ + if (request2.readyState == 4) { + if (callback!=null) { callback.call(); } else { window.location=host.concat(logoutURL);} + } + } + + } + } + } + else { + var request = ((window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP")); + request.open("GET", host.concat(logoutURL), true, "logout", "logout"); + request.send(""); + request.onreadystatechange = function(){ + if (request.status==401 || request.status==403 ) { window.location=host.concat(logoutURL); + } + } + } +}; + + +ROC_AUTH.remove = function (id) +{ + var element = document.getElementById(id); + element.outerHTML = ""; + delete element; + return; +}; + + + +$(document).ready(function() { + + if (typeof String.prototype.contains != 'function') { + String.prototype.contains = function (str){ + return this.indexOf(str) != -1; + }; + } + ROC_AUTH.progressive_loging(); + +}); + + +ROC_AUTH.progressive_loging = function () { + + ROC_AUTH.login_href(); +}; + + +$(document).keypress(function(e) { + if ((e.which === 13) && (e.target.localName === 'input' && e.target.id === 'password')) { + ROC_AUTH.login(); + } +}); + +ROC_AUTH.OnOneClick = function(event) { + event.preventDefault(); + if ( document.forms[0] === undefined ) { + ROC_AUTH.create_form(); + } + return false; +}; + +ROC_AUTH.login_href = function() { + var els = document.getElementsByTagName("a"); + for (var i = 0, l = els.length; i < l; i++) { + var el = els[i]; + if (el.href.contains("/basic_auth_login?destination")) { + loginURL = el.href; + var OneClick = el; + OneClick.addEventListener('click', ROC_AUTH.OnOneClick, false); + } + } +}; + + +ROC_AUTH.create_form = function() { + + // Fetching HTML Elements in Variables by ID. + var createform = document.createElement('form'); // Create New Element Form + createform.setAttribute("action", ""); // Setting Action Attribute on Form + createform.setAttribute("method", "post"); // Setting Method Attribute on Form + $("body").append(createform); + + var heading = document.createElement('h2'); // Heading of Form + heading.innerHTML = "Login Form "; + createform.appendChild(heading); + + var line = document.createElement('hr'); // Giving Horizontal Row After Heading + createform.appendChild(line); + + var linebreak = document.createElement('br'); + createform.appendChild(linebreak); + + var namelabel = document.createElement('label'); // Create Label for Name Field + namelabel.innerHTML = "Username : "; // Set Field Labels + createform.appendChild(namelabel); + + var inputelement = document.createElement('input'); // Create Input Field for UserName + inputelement.setAttribute("type", "text"); + inputelement.setAttribute("name", "username"); + inputelement.setAttribute("required","required"); + createform.appendChild(inputelement); + + var linebreak = document.createElement('br'); + createform.appendChild(linebreak); + + var passwordlabel = document.createElement('label'); // Create Label for Password Field + passwordlabel.innerHTML = "Password : "; + createform.appendChild(passwordlabel); + + var passwordelement = document.createElement('input'); // Create Input Field for Password. + passwordelement.setAttribute("type", "password"); + passwordelement.setAttribute("name", "password"); + passwordelement.setAttribute("id", "password"); + passwordelement.setAttribute("required","required"); + createform.appendChild(passwordelement); + + + var passwordbreak = document.createElement('br'); + createform.appendChild(passwordbreak); + + + var submitelement = document.createElement('button'); // Append Submit Button + submitelement.setAttribute("type", "button"); + submitelement.setAttribute("onclick", "ROC_AUTH.login();"); + submitelement.innerHTML = "Sign In "; + createform.appendChild(submitelement); + +}; + + +var password = document.getElementById("password") + , confirm_password = document.getElementById("confirm_password"); + +ROC_AUTH.validatePassword =function(){ + if(password.value != confirm_password.value) { + confirm_password.setCustomValidity("Passwords Don't Match"); + } else { + confirm_password.setCustomValidity(''); + } +} + +password.onchange = ROC_AUTH.validatePassword(); +confirm_password.onkeyup = ROC_AUTH.validatePassword; \ No newline at end of file diff --git a/modules/auth/site/templates/block_login.tpl b/modules/auth/site/templates/block_login.tpl new file mode 100644 index 0000000..0549b24 --- /dev/null +++ b/modules/auth/site/templates/block_login.tpl @@ -0,0 +1,34 @@ +
+ {unless isset="$user"} +

Login or Register

+
+
+
+
+ + +
+ +
+ + +
+ + +
+
+
+
+
+

+ Forgot password? +

+
+
+
+ {foreach item="item" from="$oauth_consumers"} + Login with {$item/}
+ {/foreach} +
+ {/unless} +
diff --git a/modules/basic_auth/site/templates/block_new_password.tpl b/modules/auth/site/templates/block_new_password.tpl similarity index 100% rename from modules/basic_auth/site/templates/block_new_password.tpl rename to modules/auth/site/templates/block_new_password.tpl diff --git a/modules/basic_auth/site/templates/block_post_password.tpl b/modules/auth/site/templates/block_post_password.tpl similarity index 100% rename from modules/basic_auth/site/templates/block_post_password.tpl rename to modules/auth/site/templates/block_post_password.tpl diff --git a/modules/basic_auth/site/templates/block_post_reactivate.tpl b/modules/auth/site/templates/block_post_reactivate.tpl similarity index 100% rename from modules/basic_auth/site/templates/block_post_reactivate.tpl rename to modules/auth/site/templates/block_post_reactivate.tpl diff --git a/modules/basic_auth/site/templates/block_post_register.tpl b/modules/auth/site/templates/block_post_register.tpl similarity index 100% rename from modules/basic_auth/site/templates/block_post_register.tpl rename to modules/auth/site/templates/block_post_register.tpl diff --git a/modules/basic_auth/site/templates/block_post_reset.tpl b/modules/auth/site/templates/block_post_reset.tpl similarity index 100% rename from modules/basic_auth/site/templates/block_post_reset.tpl rename to modules/auth/site/templates/block_post_reset.tpl diff --git a/modules/basic_auth/site/templates/block_reactivate.tpl b/modules/auth/site/templates/block_reactivate.tpl similarity index 100% rename from modules/basic_auth/site/templates/block_reactivate.tpl rename to modules/auth/site/templates/block_reactivate.tpl diff --git a/modules/basic_auth/site/templates/block_register.tpl b/modules/auth/site/templates/block_register.tpl similarity index 100% rename from modules/basic_auth/site/templates/block_register.tpl rename to modules/auth/site/templates/block_register.tpl diff --git a/modules/basic_auth/site/templates/block_reset_password.tpl b/modules/auth/site/templates/block_reset_password.tpl similarity index 100% rename from modules/basic_auth/site/templates/block_reset_password.tpl rename to modules/auth/site/templates/block_reset_password.tpl diff --git a/modules/basic_auth/basic_auth_module.e b/modules/basic_auth/basic_auth_module.e index f604f59..b2308ef 100644 --- a/modules/basic_auth/basic_auth_module.e +++ b/modules/basic_auth/basic_auth_module.e @@ -52,12 +52,6 @@ feature -- Access: router configure_api_login (a_api, a_router) configure_api_logoff (a_api, a_router) a_router.handle ("/account/roc-basic-auth", create {WSF_URI_AGENT_HANDLER}.make (agent handle_login_basic_auth (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/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) - end feature -- Access: filter @@ -104,215 +98,6 @@ feature {NONE} -- Implementation: routes r.execute end - - handle_register (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) - local - r: CMS_RESPONSE - l_user_api: CMS_USER_API - u: CMS_USER - l_roles: LIST [CMS_USER_ROLE] - l_exist: BOOLEAN - es: CMS_AUTHENTICATON_EMAIL_SERVICE - l_url: STRING - l_token: STRING - do - create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - r.set_value ("Register", "optional_content_type") - 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 - then - l_user_api := api.user_api - - if attached l_user_api.user_by_name (l_name.value) then - -- Username already exist. - r.values.force ("The user name exist!", "error_name") - l_exist := True - end - if attached l_user_api.user_by_email (l_email.value) then - -- Emails already exist. - r.values.force ("The email exist!", "error_email") - l_exist := True - end - - if not l_exist then - -- New user - create {ARRAYED_LIST [CMS_USER_ROLE]}l_roles.make (1) - l_roles.force (l_user_api.authenticated_user_role) - - create u.make (l_name.value) - u.set_email (l_email.value) - u.set_password (l_password.value) - u.set_roles (l_roles) - l_user_api.new_user (u) - - -- Create activation token - l_token := new_token - l_user_api.new_activation (l_token, u.id) - l_url := req.absolute_script_url ("/account/activate/" + l_token) - - -- Send Email - create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) - write_debug_log (generator + ".handle register: send_contact_email") - es.send_contact_email (l_email.value, l_url) - - else - r.values.force (l_name.value, "name") - r.values.force (l_email.value, "email") - r.set_status_code ({HTTP_CONSTANTS}.bad_request) - end - end - end - - r.execute - end - - handle_activation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) - local - r: CMS_RESPONSE - l_user_api: CMS_USER_API - l_ir: INTERNAL_SERVER_ERROR_CMS_RESPONSE - do - 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 attached {CMS_USER} l_user_api.user_by_activation_token (l_token.value) as l_user then - -- Valid user_id - l_user.mark_active - l_user_api.update_user (l_user) - l_user_api.remove_activation (l_token.value) - r.set_value ("Account activated", "optional_content_type") - r.set_main_content ("

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

") - else - -- the token does not exist, or it was already used. - r.set_status_code ({HTTP_CONSTANTS}.bad_request) - r.set_value ("Account not activated", "optional_content_type") - r.set_main_content ("

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

") - end - r.execute - else - create l_ir.make (req, res, api) - l_ir.execute - end - end - - - handle_reactivation (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) - local - r: CMS_RESPONSE - es: CMS_AUTHENTICATON_EMAIL_SERVICE - l_user_api: CMS_USER_API - l_token: STRING - l_url: STRING - do - 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_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 l_user.is_active then - r.values.force ("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 := req.absolute_script_url ("/account/activate/" + l_token) - - -- Send Email - create es.make (create {CMS_AUTHENTICATION_EMAIL_SERVICE_PARAMETERS}.make (api)) - write_debug_log (generator + ".handle register: send_contact_activation_email") - es.send_contact_activation_email (l_email.value, l_url) - end - else - r.values.force ("The email does not exist or !", "error_email") - r.values.force (l_email.value, "email") - r.set_status_code ({HTTP_CONSTANTS}.bad_request) - end - end - end - - r.execute - end - - handle_new_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) - local - r: CMS_RESPONSE - es: CMS_AUTHENTICATON_EMAIL_SERVICE - l_user_api: CMS_USER_API - l_token: STRING - l_url: STRING - do - create {GENERIC_VIEW_CMS_RESPONSE} r.make (req, res, api) - 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. - 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 - 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) - else - r.values.force ("The email does not exist !", "error_email") - r.values.force (l_email.value, "email") - r.set_status_code ({HTTP_CONSTANTS}.bad_request) - end - end - end - r.execute - end - - - handle_reset_password (api: CMS_API; req: WSF_REQUEST; res: WSF_RESPONSE) - local - r: CMS_RESPONSE - l_user_api: CMS_USER_API - 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 - r.values.force (l_token.value, "token") - if l_user_api.user_by_password_token (l_token.value) = Void then - r.values.force ("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 l_password.value.same_string (l_confirm_password.value) then - -- 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) - l_user_api.remove_password (l_token.value) - end - else - r.values.force ("Passwords Don't Match", "error_password") - r.values.force (l_token.value, "token") - r.set_status_code ({HTTP_CONSTANTS}.bad_request) - end - end - end - r.execute - end - feature -- Hooks configuration register_hooks (a_response: CMS_RESPONSE) @@ -371,7 +156,7 @@ feature -- Hooks local l_string: STRING do - Result := <<"login", "register", "reactivate", "new_password", "reset_password">> + Result := <<"login">> debug ("roc") create l_string.make_empty across @@ -392,51 +177,9 @@ feature -- Hooks then a_response.add_javascript_url (a_response.url ("module/" + name + "/files/js/roc_auth.js", Void)) get_block_view_login (a_block_id, a_response) - elseif - 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 - 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 - 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 - get_block_view_reset_password (a_block_id, a_response) end end - -feature {NONE} -- Token Generation - - new_token: STRING - -- Generate a new token activation token - local - l_token: STRING - l_security: SECURITY_PROVIDER - l_encode: URL_ENCODER - do - 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. - l_token := l_security.token - end - Result := l_token - end - feature {NONE} -- Helpers template_block (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE): detachable CMS_SMARTY_TEMPLATE_BLOCK @@ -480,142 +223,4 @@ feature {NONE} -- Block views end end - get_block_view_register (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) - do - if a_response.request.is_get_request_method then - if attached template_block (a_block_id, a_response) as l_tpl_block then - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - 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") - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - else - if attached template_block ("post_register", a_response) as l_tpl_block then - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - end - end - end - - - get_block_view_reactivate (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) - do - if a_response.request.is_get_request_method then - if attached template_block (a_block_id, a_response) as l_tpl_block then - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - 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") - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - else - if attached template_block ("post_reactivate", a_response) as l_tpl_block then - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - end - end - end - - get_block_view_new_password (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) - do - if a_response.request.is_get_request_method then - if attached template_block (a_block_id, a_response) as l_tpl_block then - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - elseif a_response.request.is_post_request_method then - if 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_email"), "error_email") - l_tpl_block.set_value (a_response.values.item ("email"), "email") - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - else - if attached template_block ("post_password", a_response) as l_tpl_block then - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - end - end - end - - get_block_view_reset_password (a_block_id: READABLE_STRING_8; a_response: CMS_RESPONSE) - 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") - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - 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 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") - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - else - if attached template_block ("post_reset", a_response) as l_tpl_block then - a_response.add_block (l_tpl_block, "content") - else - debug ("cms") - a_response.add_warning_message ("Error with block [" + a_block_id + "]") - end - end - end - end - end end