diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/auth_totp/static | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/auth_totp/static')
| -rw-r--r-- | addons/auth_totp/static/tests/totp_flow.js | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/addons/auth_totp/static/tests/totp_flow.js b/addons/auth_totp/static/tests/totp_flow.js new file mode 100644 index 00000000..eea24504 --- /dev/null +++ b/addons/auth_totp/static/tests/totp_flow.js @@ -0,0 +1,247 @@ +odoo.define('auth_totp.tours', function(require) { +"use strict"; + +const tour = require('web_tour.tour'); +const ajax = require('web.ajax'); + +function openRoot() { + return [{ + content: "return to client root to avoid race condition", + trigger: 'body', + run() { + $('body').addClass('wait'); + window.location = '/web'; + } + }, { + content: "wait for client reload", + trigger: 'body:not(.wait)', + run() {} + }]; +} +function openUserProfileAtSecurityTab() { + return [{ + content: 'Open user account menu', + trigger: '.o_user_menu .oe_topbar_name', + run: 'click', + }, { + content: "Open preferences / profile screen", + trigger: '[data-menu=settings]', + run: 'click', + }, { + content: "Switch to security tab", + trigger: 'a[role=tab]:contains("Account Security")', + run: 'click', + }]; +} + +tour.register('totp_tour_setup', { + test: true, + url: '/web' +}, [...openUserProfileAtSecurityTab(), { + content: "Open totp wizard", + trigger: 'button[name=totp_enable_wizard]', +}, { + content: "Check that we have to enter enhanced security mode", + trigger: 'div:contains("confirm your password")', + run: () => {}, +}, { + content: "Input password", + trigger: '[name=password]', + run: 'text demo', // FIXME: better way to do this? +}, { + content: "Confirm", + trigger: "button:contains(Confirm Password)", +}, { + content: "Check the wizard has opened", + trigger: 'div:contains("Scan the image below")', + run: () => {} +}, { + content: "Get secret from collapsed div", + trigger: 'a:contains("show the code")', + run(helpers) { + const secret = this.$anchor.closest('div').find('code').text(); + ajax.jsonRpc('/totphook', 'call', { + secret + }).then((token) => { + helpers._text(helpers._get_action_values('input[name=code]'), token); + helpers._click(helpers._get_action_values('button.btn-primary:contains(Enable)')); + $('body').addClass('got-token') + }); + } +}, { + content: 'wait for rpc', + trigger: 'body.got-token', + run() {} +}, +...openRoot(), +...openUserProfileAtSecurityTab(), +{ + content: "Check that the button has changed", + trigger: 'button:contains(Disable two-factor authentication)', + run: () => {} +}]); + +tour.register('totp_login_enabled', { + test: true, + url: '/' +}, [{ + content: "check that we're on the login page or go to it", + trigger: 'input#login, a:contains(Sign in)' +}, { + content: "input login", + trigger: 'input#login', + run: 'text demo', +}, { + content: 'input password', + trigger: 'input#password', + run: 'text demo', +}, { + content: "click da button", + trigger: 'button:contains("Log in")', +}, { + content: "expect totp screen", + trigger: 'label:contains(Authentication Code)', +}, { + content: "input code", + trigger: 'input[name=totp_token]', + run(helpers) { + ajax.jsonRpc('/totphook', 'call', {}).then((token) => { + helpers._text(helpers._get_action_values(), token); + // FIXME: is there a way to put the button as its own step trigger without + // the tour straight blowing through and not waiting for this? + helpers._click(helpers._get_action_values('button:contains("Verify")')); + }); + } +}, { + content: "check we're logged in", + trigger: ".o_user_menu .oe_topbar_name", + run: () => {} +}, +// now go and disable totp would be annoying to do in a separate tour +// because we'd need to login & totp again as HttpCase.authenticate can't +// succeed w/ totp enabled +...openUserProfileAtSecurityTab(), +{ + content: "Open totp wizard", + trigger: 'button[name=totp_disable]', +}, { + content: "Check that we have to enter enhanced security mode", + trigger: 'div:contains("confirm your password")', + run: () => {}, +}, { + content: "Input password", + trigger: '[name=password]', + run: 'text demo', // FIXME: better way to do this? +}, { + content: "Confirm", + trigger: "button:contains(Confirm Password)", +}, +...openRoot(), +...openUserProfileAtSecurityTab(), +{ + content: "Check that the button has changed", + trigger: 'button:contains(Enable two-factor authentication)', + run: () => {} +}]); + +tour.register('totp_login_disabled', { + test: true, + url: '/' +}, [{ + content: "check that we're on the login page or go to it", + trigger: 'input#login, a:contains(Sign in)' +}, { + content: "input login", + trigger: 'input#login', + run: 'text demo', +}, { + content: 'input password', + trigger: 'input#password', + run: 'text demo', +}, { + content: "click da button", + trigger: 'button:contains("Log in")', +}, +// normally we'd end the tour here as it's all we care about but there are a +// bunch of ongoing queries from the loading of the web client which cause +// issues, so go and open the preferences / profile screen to make sure +// everything settles down +...openUserProfileAtSecurityTab(), +]); + +const columns = {}; +tour.register('totp_admin_disables', { + test: true, + url: '/web' +}, [tour.stepUtils.showAppsMenuItem(), { + content: 'Go to settings', + trigger: '[data-menu-xmlid="base.menu_administration"]' +}, { + content: 'Wait for page', + trigger: '.o_menu_brand:contains("Settings")', + run: () => {} +}, { + content: "Open Users menu", + trigger: '[data-menu-xmlid="base.menu_users"]' +}, { + content: "Open Users view", + trigger: '[data-menu-xmlid="base.menu_action_res_users"]', + run: function (helpers) { + // funny story: the users view we're trying to reach, sometimes we're + // already there, but if we re-click the next step executes before the + // action has the time to re-load, the one after that doesn't, and our + // selection get discarded by the action reloading, so here try to + // see if we're already on the users action through the breadcrumb and + // just close the menu if so + const $crumb = $('.breadcrumb'); + if ($crumb.text().indexOf('Users') === -1) { + // on general settings page, click menu + helpers.click(); + } else { + // else close menu + helpers.click($('[data-menu-xmlid="base.menu_users"]')); + } + } +}, { + content: "Find Demo User", + trigger: 'td.o_data_cell:contains("demo")', + run: function (helpers) { + const $titles = this.$anchor.closest('table').find('tr:first th'); + for (let i=0; i<$titles.length; ++i) { + columns[$titles[i].getAttribute('data-name')] = i; + } + const $row = this.$anchor.closest('tr'); + const sel = $row.find('.o_list_record_selector input[type=checkbox]'); + const totp = $row[0].children[columns['totp_enabled']].querySelector('input'); + if (totp.checked) { + helpers.click(sel); + } + } +}, { + content: "Open Actions menu", + trigger: 'button.o_dropdown_toggler_btn:contains("Action")' +}, { + content: "Select totp remover", + trigger: 'a.dropdown-item:contains(Disable TOTP on users)' +}, { // enhanced security yo + content: "Check that we have to enter enhanced security mode", +trigger: 'div:contains("confirm your password")', + run: () => {}, +}, { + content: "Input password", + trigger: '[name=password]', + run: 'text admin', // FIXME: better way to do this? +}, { + content: "Confirm", + trigger: "button:contains(Confirm Password)", +}, { + content: "check that demo user has been de-totp'd", + trigger: "td.o_data_cell:contains(demo)", + run: function () { + const totpcell = this.$anchor.closest('tr')[0].children[columns['totp_enabled']]; + if (totpcell.querySelector('input').checked) { + throw new Error("totp should have been disabled on demo user"); + } + } +}]) +}); |
