Redo auth flow with lit. Beef up the test a bit, accordingly.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4392 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
1ba37d95b5
commit
70d37c88b5
103
core/auth.html
103
core/auth.html
@ -10,10 +10,109 @@
|
|||||||
<link type="text/css" rel="stylesheet" href="/static/style.css">
|
<link type="text/css" rel="stylesheet" href="/static/style.css">
|
||||||
<link type="image/png" rel="shortcut icon" href="/static/favicon.png">
|
<link type="image/png" rel="shortcut icon" href="/static/favicon.png">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<!--HEAD-->
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1 style="text-align: center">Tilde Friends Sign-in</h1>
|
<h1 style="text-align: center">Tilde Friends Sign-in</h1>
|
||||||
<div id="content"><!--SESSION--></div>
|
<tf-auth id="auth"></tf-auth>
|
||||||
|
<script>window.litDisableBundleWarning = true;</script>
|
||||||
|
<script type="module">
|
||||||
|
import {LitElement, html} from '/static/lit/lit-all.min.js';
|
||||||
|
let g_data = $AUTH_DATA;
|
||||||
|
let app = document.getElementById('auth');
|
||||||
|
Object.assign(app, g_data);
|
||||||
|
|
||||||
|
class TfAuthElement extends LitElement {
|
||||||
|
static get_properties() {
|
||||||
|
return {
|
||||||
|
name: {type: String},
|
||||||
|
tab: {type: String},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.tab = 'login';
|
||||||
|
}
|
||||||
|
|
||||||
|
tab_changed(name) {
|
||||||
|
this.tab = name;
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let self = this;
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
[name="tab"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
[name="tab"]+label {
|
||||||
|
background-color: #657b83;
|
||||||
|
padding: 1em;
|
||||||
|
display: inline-block;
|
||||||
|
flex: 1 0;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
[name="tab"]+label:hover {
|
||||||
|
background-color: #dc322f;
|
||||||
|
}
|
||||||
|
[name="tab"]:checked+label {
|
||||||
|
background-color: #93a1a1;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
color: #f00;
|
||||||
|
border: 1px solid #f00;
|
||||||
|
margin: 4px;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div style="display: flex; flex-direction: column">
|
||||||
|
<h1 ?hidden=${this.name}>Welcome.</h1>
|
||||||
|
<h1 ?hidden=${this.name === undefined}>Welcome, ${this.name}.</h1>
|
||||||
|
|
||||||
|
<div style="display: flex; flex-direction: row; width: 100%">
|
||||||
|
<input type="radio" name="tab" id="login" value="Login" ?checked=${this.tab == 'login'} @change=${() => self.tab_changed('login')}></input>
|
||||||
|
<label for="login" id="login_label">Login</label>
|
||||||
|
|
||||||
|
<input type="radio" name="tab" id="register" value="Register" ?checked=${this.tab == 'register'} @change=${() => self.tab_changed('register')}></input>
|
||||||
|
<label for="register" id="register_label">Register</label>
|
||||||
|
|
||||||
|
<input type="radio" name="tab" id="guest" value="Guest" ?checked=${this.tab == 'guest'} @change=${() => self.tab_changed('guest')}></input>
|
||||||
|
<label for="guest" id="guest_label">Guest</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ?hidden=${this.tab != 'login' && this.tab != 'register'}>
|
||||||
|
<div id="error" ?hidden=${this.error === undefined} class="error">
|
||||||
|
${this.error}
|
||||||
|
</div>
|
||||||
|
<form method="POST">
|
||||||
|
<div><label for="name">Name:</label> <input type="text" id="name" name="name" value=""></div>
|
||||||
|
<div><label for="password">Password:</label> <input type="password" id="password" name="password" value=""></div>
|
||||||
|
<div ?hidden=${this.tab != 'register'} id="confirmPassword"><label for="confirm">Confirm:</label> <input type="password" id="confirm" name="confirm" value=""></div>
|
||||||
|
<div><input id="loginButton" type="submit" name="submit" value="Login"></div>
|
||||||
|
<input type="hidden" name="register" value="${this.tab == 'register' ? 1 : 0}"></input>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div ?hidden=${this.tab != 'guest'}>
|
||||||
|
<form method="POST">
|
||||||
|
<input type="submit" id="guestButton" name="guestButton" value="Proceed as Guest"></input>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div ?hidden=${this.have_administrator} class="notice">
|
||||||
|
There is currently no administrator. You will be made administrator.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2>Code of Conduct</h2>
|
||||||
|
<div>
|
||||||
|
<textarea readonly rows="20" cols="80">${this.code_of_conduct}</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('tf-auth', TfAuthElement);
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
51
core/auth.js
51
core/auth.js
@ -121,6 +121,7 @@ function handler(request, response) {
|
|||||||
|
|
||||||
let formData = form.decodeForm(request.query);
|
let formData = form.decodeForm(request.query);
|
||||||
|
|
||||||
|
print(request.method, utf8Decode(request.body), JSON.stringify(formData));
|
||||||
if (request.method == "POST" || formData.submit) {
|
if (request.method == "POST" || formData.submit) {
|
||||||
sessionIsNew = true;
|
sessionIsNew = true;
|
||||||
formData = form.decodeForm(utf8Decode(request.body), formData);
|
formData = form.decodeForm(utf8Decode(request.body), formData);
|
||||||
@ -178,46 +179,16 @@ function handler(request, response) {
|
|||||||
} else {
|
} else {
|
||||||
File.readFile("core/auth.html").then(function(data) {
|
File.readFile("core/auth.html").then(function(data) {
|
||||||
let html = utf8Decode(data);
|
let html = utf8Decode(data);
|
||||||
let contents = "";
|
let auth_data = {
|
||||||
|
session_is_new: sessionIsNew,
|
||||||
if (entry) {
|
name: entry?.name,
|
||||||
if (sessionIsNew) {
|
error: loginError,
|
||||||
contents += '<div>Welcome back, ' + entry.name + '.</div>\n';
|
code_of_conduct: core.globalSettings.code_of_conduct,
|
||||||
} else {
|
have_administrator: !noAdministrator(),
|
||||||
contents += '<div>You are already logged in, ' + entry.name + '.</div>\n';
|
};
|
||||||
}
|
html = utf8Encode(html.replace('$AUTH_DATA', JSON.stringify(auth_data)));
|
||||||
contents += '<div><a href="/login/logout">Logout</a></div>\n';
|
response.writeHead(200, {"Content-Type": "text/html; charset=utf-8", "Set-Cookie": cookie, "Content-Length": html.length});
|
||||||
} else {
|
response.end(html);
|
||||||
contents += '<form method="POST">\n';
|
|
||||||
if (loginError) {
|
|
||||||
contents += "<p>" + loginError + "</p>\n";
|
|
||||||
}
|
|
||||||
contents += '<div id="auth_greeting"><b>Halt. Who goes there?</b></div>\n'
|
|
||||||
contents += '<div id="auth">\n';
|
|
||||||
contents += '<div id="auth_login">\n'
|
|
||||||
if (noAdministrator()) {
|
|
||||||
contents += '<div class="notice">There is currently no administrator. You will be made administrator.</div>\n';
|
|
||||||
}
|
|
||||||
contents += '<div><label for="name">Name:</label> <input type="text" id="name" name="name" value=""></div>\n';
|
|
||||||
contents += '<div><label for="password">Password:</label> <input type="password" id="password" name="password" value=""></div>\n';
|
|
||||||
contents += '<div id="confirmPassword" style="display: none"><label for="confirm">Confirm:</label> <input type="password" id="confirm" name="confirm" value=""></div>\n';
|
|
||||||
contents += '<div><input type="checkbox" id="register" name="register" value="1" onchange="showHideConfirm()"> <label for="register">Register a new account</label></div>\n';
|
|
||||||
contents += '<div><input id="loginButton" type="submit" name="submit" value="Login"></div>\n';
|
|
||||||
contents += '</div>';
|
|
||||||
contents += '<div class="auth_or"> - or - </div>';
|
|
||||||
contents += '<div id="auth_guest">\n';
|
|
||||||
contents += '<input id="guestButton" type="submit" name="submit" value="Proceeed as Guest">\n';
|
|
||||||
contents += '</div>\n';
|
|
||||||
contents += '</div>\n';
|
|
||||||
contents += '<div style="text-align: center">\n';
|
|
||||||
contents += '<h2>Code of Conduct</h2>\n';
|
|
||||||
contents += `<div><textarea readonly rows=20 cols=80>${core.globalSettings.code_of_conduct}</textarea></div>\n`;
|
|
||||||
contents += '</div>\n';
|
|
||||||
contents += '</form>';
|
|
||||||
}
|
|
||||||
let text = html.replace("<!--SESSION-->", contents);
|
|
||||||
response.writeHead(200, {"Content-Type": "text/html; charset=utf-8", "Set-Cookie": cookie, "Content-Length": text.length});
|
|
||||||
response.end(text);
|
|
||||||
}).catch(function(error) {
|
}).catch(function(error) {
|
||||||
response.writeHead(404, {"Content-Type": "text/plain; charset=utf-8", "Connection": "close"});
|
response.writeHead(404, {"Content-Type": "text/plain; charset=utf-8", "Connection": "close"});
|
||||||
response.end("404 File not found");
|
response.end("404 File not found");
|
||||||
|
@ -100,33 +100,6 @@ a:active {
|
|||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
#auth_greeting {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#auth {
|
|
||||||
display: flex;
|
|
||||||
flex-flow: row;
|
|
||||||
align-content: center;
|
|
||||||
align-items: center;
|
|
||||||
text-align: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#auth_login {
|
|
||||||
flex: 0 1 auto;
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.auth_or {
|
|
||||||
flex: 0 1 auto;
|
|
||||||
padding: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
#auth_guest {
|
|
||||||
flex: 0 1 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notice {
|
.notice {
|
||||||
color: #cb4b16;
|
color: #cb4b16;
|
||||||
margin: 1em;
|
margin: 1em;
|
||||||
|
@ -23,19 +23,21 @@ try:
|
|||||||
options = webdriver.FirefoxOptions()
|
options = webdriver.FirefoxOptions()
|
||||||
#options.add_argument('--headless')
|
#options.add_argument('--headless')
|
||||||
driver = webdriver.Firefox(options = options)
|
driver = webdriver.Firefox(options = options)
|
||||||
wait = WebDriverWait(driver, 30)
|
wait = WebDriverWait(driver, 10)
|
||||||
driver.get('http://localhost:8888')
|
driver.get('http://localhost:8888')
|
||||||
driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'login').click()
|
driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'login').click()
|
||||||
driver.find_element(By.ID, 'register').click()
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'register_label').click()
|
||||||
driver.find_element(By.ID, 'name').send_keys('test_user')
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('test_user')
|
||||||
driver.find_element(By.ID, 'password').send_keys('test_password')
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
|
||||||
driver.find_element(By.ID, 'confirm').send_keys('test_password')
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'confirm').send_keys('test_password')
|
||||||
driver.find_element(By.ID, 'loginButton').click()
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
|
||||||
|
|
||||||
|
wait.until(expected_conditions.presence_of_element_located((By.ID, 'document')))
|
||||||
driver.switch_to.frame(driver.find_element(By.ID, 'document'))
|
driver.switch_to.frame(driver.find_element(By.ID, 'document'))
|
||||||
wait.until(expected_conditions.presence_of_element_located((By.LINK_TEXT, 'ssb'))).click()
|
wait.until(expected_conditions.presence_of_element_located((By.LINK_TEXT, 'ssb'))).click()
|
||||||
driver.switch_to.default_content()
|
driver.switch_to.default_content()
|
||||||
|
|
||||||
|
wait.until(expected_conditions.presence_of_element_located((By.ID, 'content')))
|
||||||
driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))))
|
driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))))
|
||||||
tf_app = wait.until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'tf-app'))).shadow_root
|
tf_app = wait.until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'tf-app'))).shadow_root
|
||||||
wait.until(expected_conditions.element_to_be_clickable(tf_app.find_element(By.ID, 'create_identity'))).click()
|
wait.until(expected_conditions.element_to_be_clickable(tf_app.find_element(By.ID, 'create_identity'))).click()
|
||||||
@ -48,6 +50,36 @@ try:
|
|||||||
driver.switch_to.default_content()
|
driver.switch_to.default_content()
|
||||||
driver.find_element(By.ID, 'allow').click()
|
driver.find_element(By.ID, 'allow').click()
|
||||||
|
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'logout test_user').click()
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'login_label').click()
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('test_user')
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
|
||||||
|
|
||||||
|
wait.until(expected_conditions.presence_of_element_located((By.ID, 'content')))
|
||||||
|
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'logout test_user').click()
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'guest_label').click()
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'guestButton').click()
|
||||||
|
|
||||||
|
wait.until(expected_conditions.presence_of_element_located((By.ID, 'content')))
|
||||||
|
driver.switch_to.frame(wait.until(expected_conditions.presence_of_element_located((By.ID, 'document'))))
|
||||||
|
wait.until(expected_conditions.presence_of_element_located((By.TAG_NAME, 'tf-app'))).shadow_root
|
||||||
|
driver.switch_to.default_content()
|
||||||
|
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-navigation').shadow_root.find_element(By.LINK_TEXT, 'logout guest').click()
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'login_label').click()
|
||||||
|
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('test_user')
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('wrong_password')
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'error')
|
||||||
|
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'name').send_keys('wrong_user')
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'password').send_keys('test_password')
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'loginButton').click()
|
||||||
|
driver.find_element(By.TAG_NAME, 'tf-auth').shadow_root.find_element(By.ID, 'error')
|
||||||
|
|
||||||
print('SUCCESS.')
|
print('SUCCESS.')
|
||||||
finally:
|
finally:
|
||||||
driver.close()
|
driver.close()
|
||||||
|
Loading…
Reference in New Issue
Block a user