Unverified Commit afa0cd31 authored by Maarten de Waard's avatar Maarten de Waard 🤘🏻
Browse files

remove getGrade and getState from problems because they do not work anymore

parent 382f3827
Pipeline #13799 passed with stages
in 38 seconds
......@@ -16,22 +16,19 @@ totp-problem
------------
The 'totp-problem' teaches people how to use TOTP a.k.a. Google Authenticator.
It features all the bells and whistles a *"Javascript Display and Grading"*
problem can have, so it may be a good starting point for your own problem.
.. Note::
To solve this problem, students need to have a smartphone in their
possession. Please take this into consideration when composing a course, if
it is likely some students do not have a smartphone they can use for
solving the problem, they will not be able to get a perfect score.
Students have to follow these steps to get a "good" (it's either correct or
false) grade:
Students have to follow these steps:
- Read introduction on TOTP/Google Authenticator and acquiring the required
App. Either download it, or already have one installed.
- Read introduction on TOTP/Google Authenticator and acquire the required App.
- Create an account in a fictional social network.
- Password has to be strong, follows OWASP guidelines.
- Password has to be strong, follows ``password-problem`` guidelines.
- Login with the account that was created in the previous step.
- Find the *Settings* page and the *Enable Multifacto Authentication* button
within it.
......@@ -51,11 +48,9 @@ information is gathered from https://ip.micro.greenhost.net/lookup
password-problem
----------------
There are two password problems. Each of them consist of a password entry box.
One of them provides hints about how the entered password can be improved. The
``no_hint`` version only scores the strength of the passwords. The
``how-secure-is-my-password`` javascript package is used to grade password
strength and provide hints.
The password problem consist of a password entry box. The ``zxcvbn`` javascript
package is used to grade password strength and provide hints. The hints are
shown below the password entry box.
How to use this
###############
......@@ -144,47 +139,10 @@ the application is delivered in, containing the html files for that locale.
Adding the problem to a course
------------------------------
You can add a problem as a "Javascript Display and Grading", or as HTML only.
The first option contains a Submit button, applicable for example to check if
the problem was completed successfully. The latter is simpler to set up,
but has no submit button.
For the submit button to work, the
problem needs to be hosted with the same domain namne as your edX instance. We chose to host our problems
via a proxy available in the CMS *and* LMS at `/js-components/`.
Adding a problem with a Submit button
+++++++++++++++++++++++++++++++++++++
First, make the problems available at
``/js-components/<locale>/<problem>.html`` (for example
https://learn.totem-project.org/js-components/en/problem_password.html).
- Add New Component: **Problem**
- Click on **Advanced**
- Click on **Custom JavaScript Display and Grading**
- Click on **Edit**
- Now, you need to paste the contents from this repository's
``examples/<your-problem>.html`` into the editor.
- Make sure the ``html_file`` attribute contains a link to the locale your
course is in.
- **Optional**:
- Click on **Settings**
- Find **Maximum attempts** and set it to something above ``0``, it will
allow the student to try to submit the answer multiple times but it will
also enable the "Save" button which will allow the user to save the state
of the problem and return to it, even after logging out and back in.
You can add a problem by including them in an iFrame.
- **Optional**:
- Click on **Settings**
- Find **Show reset button** and set it to ``True``, this will allow
students to reset the state of the problem.
Adding a problem without a Submit button
++++++++++++++++++++++++++++++++++++++++
Adding a problem
++++++++++++++++
- Add New Component: **Problem**
- Click on **HTML**
......@@ -193,38 +151,7 @@ Adding a problem without a Submit button
- Now, you need to paste the contents from this repository's
``examples/<your-problem.html>-no-submit-button.html`` into the editor.
- Make sure the ``src`` attribute contains a link to the locale your course is
in.
- **NOTE**
- If you don't need a submit button you don't need to have your problems
hosted on your edX instance. You can use
``src="//totem-project.org/js-components/<locale>/<problem>`` in the iframe.
Setting up a proxy for problems with a submit button
++++++++++++++++++++++++++++++++++++++++++++++++++++
The Submit button of a JavaScript Display and Grading problem in edX tries to
access the javascript inside the iframe. For this to work, the iframe needs to
be hosted on the same domain as the learning environment. For that reason, we
set up a proxy. To set up a proxy on your edX instance you need to edit the
nginx ``lms`` and ``cms`` configuration.
- If you host with tutor (`>=10.5.1`), you can add a [custom
plugin](https://code.greenhost.net/totem/tutor-server/-/blob/main/plugins/totem-proxy.yml)
- If you don't use tutor, add this under the ``server`` definition in the
``lms`` and ``cms`` configuration files at
``/edx/app/nginx/sites-available/``:
.. code-block:: nginx
location /js-components/ {
proxy_ssl_verify on;
proxy_ssl_trusted_certificate /etc/ssl/certs/ca-certificates.crt;
proxy_pass https://totem-project.org/js-components/;
proxy_ssl_server_name on;
}
in (``//totem-project.org/js-components/<locale>/<problem>``).
Developing on this problem
--------------------------
......
<p></p>
<p>Feel free to replace this text with your own.</p>
<p></p>
<p><iframe title="Check password" src="//totem-project.org/js-components/en/problem_ip.html" marginwidth="0" marginheight="0" scrolling="no" width="402" height="202" frameborder="0">
<p><iframe title="IP checker" src="//totem-project.org/js-components/en/problem_ip.html" marginwidth="0" marginheight="0" scrolling="no" width="402" height="202" frameborder="0">
Your browser does not support IFrames.
</iframe></p>
<!--
http://edx.readthedocs.io/projects/edx-partner-course-staff/en/latest/exercises_tools/custom_javascript.html
http://edx.readthedocs.io/projects/edx-developer-guide/en/latest/extending_platform/javascript.html
-->
<problem>
<customresponse cfn="check_function">
<script type="loncapa/python">
<![CDATA[
import json
def check_function(e, resp):
"""
Check that the answer in the response equals True (problem solved).
"""
resp = json.loads(resp)
# You can use the value of the answer key to grade:
return json.loads(resp["answer"]) == True]]>
</script>
<jsinput
gradefn="getGrade"
get_statefn="getState"
set_statefn="setState"
initial_state=''
width="600"
height="750"
html_file="/js-components/en/problem_totp.html"
title="Multi Factor Authentication problem"
sop="true"/>
</customresponse>
</problem>
<p></p>
<p>Feel free to replace this text with your own.</p>
<p></p>
<p><iframe title="TOTP example" src="//totem-project.org/js-components/en/problem_totp.html" marginwidth="0" marginheight="0" scrolling="no" width="850" height="600" frameborder="0">
Your browser does not support IFrames.
</iframe></p>
......@@ -6,7 +6,7 @@ if (typeof window.zxcvbn == 'undefined') {
window.zxcvbn = require('@contentpass/zxcvbn');
}
window.pwcheck = function (inputElement, showHints, debug) {
window.pwcheck = function (inputElement, debug) {
if (!inputElement) {
return; // No input element so nothing to do.
}
......@@ -16,33 +16,23 @@ window.pwcheck = function (inputElement, showHints, debug) {
feedback_messages: pwcheck_translations.feedback
};
if (showHints) {
// Create an element for the hints dropdown:
var $hints = $('<div/>').addClass('pwcheck-hints');
// Do not show the hints dropdown yet, but insert it in the DOM:
$hints.hide().insertAfter($password);
// Add event listeners that manipulate the hints dropdown:
$password.on("focus input", function() {
if ($password.val() == '') {
$hints.fadeOut();
} else {
$hints.fadeIn();
}
}).on("blur", function() {
// Create an element for the hints dropdown:
var $hints = $('<div/>').addClass('pwcheck-hints');
// Do not show the hints dropdown yet, but insert it in the DOM:
$hints.hide().insertAfter($password);
// Add event listeners that manipulate the hints dropdown:
$password.on("focus input", function() {
if ($password.val() == '') {
$hints.fadeOut();
}).on("input", function() {
// This will build the hints dropdown content and apply styling:
updateHints();
});
} else {
// Don't show hints, just analyze whether the password "passes the test":
$password.on("input", function() {
var input = $password.val();
var result = zxcvbn(input, options);
// This class has no CSS styling, but getGrade() uses it:
$password.toggleClass('pwcheck-passed', result.score == 4);
});
}
} else {
$hints.fadeIn();
}
}).on("blur", function() {
$hints.fadeOut();
}).on("input", function() {
// This will build the hints dropdown content and apply styling:
updateHints();
});
/**
* Creates a five-block strength indicator, coloured via CSS classes.
......
......@@ -235,46 +235,12 @@ class @TotpChallenge extends @Totp
'login': 'login'
'settings': 'settings'
'mfa_failed': 'mfa_verification': 'mfa_verification'
@log "Binding getState, setState, getGrade to window object"
window.getState = @getState
window.setState = @setState
window.getGrade = @getGrade
@log "Calling parent with #{JSON.stringify(challenge_settings)}"
super challenge_settings or {}, @debug
if debug
# debug account
@_createAccount "user", "pass"
getState: =>
@state.secret = @secret || null
@log "getState called, returning: #{JSON.stringify(@state)}"
JSON.stringify @state
setState: (new_state) =>
if typeof new_state == 'string'
new_state = JSON.parse new_state
@log "setState was called with new state: #{JSON.stringify(new_state)}"
@stateMachine new_state.state, null, true
@salt = CryptoJS.enc.Hex.parse new_state.salt
@username = new_state.username
if @username?
@injectQrCode @qr_element
@setSecret new_state.secret
@state = new_state
if @state.solved and not @state.submitted
$("#success_modal").fadeIn()
if @state.solved and @state.submitted
$("#end_modal").fadeIn()
$("#mfa_enable_button").prop "disabled", @state.mfa_enabled
getGrade: =>
if @state.solved
$("#success_modal").fadeOut ->
$("#end_modal").fadeIn()
@state.submitted = true
@log "getGrade was called, returning: #{@state.solved}"
JSON.stringify @state.solved
###
# Reset errors
# Removes errors from any .error_list and hides .error_divs
......
......@@ -26,13 +26,5 @@ html
script(type="text/javascript").
'use strict';
var inputElement = document.getElementById("password");
var showHints = true;
var debug = #{debug};
pwcheck(inputElement, showHints, debug);
window.getGrade = function() {
var solved = inputElement.classList.contains('pwcheck-passed');
if (debug) {
console.log("getGrade was called, returning: " + solved);
}
return JSON.stringify(solved);
}
pwcheck(inputElement, debug);
doctype html
html
head
meta(charset="utf-8")
title=page_title
if debug
script(type="text/javascript" src="http://localhost:35729/livereload.js")
if rtl_locales.indexOf(locale) > -1
- dir = 'rtl'
link(rel="stylesheet" type="text/css" href=`${css_path}pwcheck-rtl.css`)
else
- dir = 'ltr'
link(rel="stylesheet" type="text/css" href=`${css_path}pwcheck-ltr.css`)
body(dir=dir)
label.field-label(for="password-box")= __("Password")
input#password.field-input.input-text(type="password")
if debug
script(type="text/javascript" src=`${js_path}pwcheck.js`)
else
script(type="text/javascript" src=`${js_path}pwcheck.min.js`)
include pwcheck_messages.pug
script(type="text/javascript").
'use strict';
var inputElement = document.getElementById("password");
var showHints = false;
var debug = #{debug};
pwcheck(inputElement, showHints, debug);
window.getGrade = function() {
var solved = inputElement.classList.contains('pwcheck-passed');
if (debug) {
console.log("getGrade was called, returning: " + solved);
}
return JSON.stringify(solved);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment