diff --git a/README.md b/README.md index 0b700fd..6402d3d 100644 --- a/README.md +++ b/README.md @@ -1,82 +1,51 @@ # Getting Started -Latest review: 2021-07-08 +Latest review: 2021-11-08 ## Installation To complete the installation we will need to perform the following steps: -1. install python3, pip and npm -2. download aprendizations from the repository -3. install javascript libraries (with npm) -4. install aprendizations (with pip) -5. generate SSL certificates -6. configure the firewall (optional) +1. install python3 and pip +2. install aprendizations +3. generate SSL certificates +4. configure the firewall (optional) To use the software we need to: -1. initialize database +1. initialize a database 2. go to the demo directory (or an existing course) -3. run `aprendizations demo.yaml` +3. run `aprendizations courses.yaml` Each of these steps is explained below. -### Install python3 with sqlite3 support and npm +### Install python3 with sqlite3 support -Python can be installed either from the system package management or compiled -from sources. - -#### Installing from the system package manager - -```sh -sudo pkg install python3 npm # FreeBSD -sudo apt install python3 npm # Linux (Ubuntu) -sudo port install python38 npm7 # MacOS -``` - -In FreeBSD also install `py3X-sqlite3` where `X` is the python version. - -#### Installing from source (outdated) - -Make sure that the build tools and libraries are installed: +Minimum supported version is python3.8. The installed versions depend on the +operating system default. ```sh -# Ubuntu: -sudo apt install build-essential libssl-dev zlib1g-dev libncurses5-dev \ - libncursesw5-dev libreadline-dev libsqlite3-dev libgdbm-dev libdb5.3-dev \ - libbz2-dev libexpat1-dev liblzma-dev tk-dev libffi-dev +sudo pkg install python3 py38-sqlite3 # FreeBSD +sudo apt install python3 # Linux (Ubuntu) +sudo port install python39 # MacOS ``` -Download [python](http://www.python.org) and - -```sh -tar xvfJ Python-3.7.tar.xz -cd Python-3.7 -./configure --prefix=$HOME/.local --enable-optimizations -make && make install -``` - -This will install python locally under `~/.local/bin`. Make sure to add it to -your `PATH` in `~/.profile`. If `~/bin` is already in the path, just make a -symbolic link `ln -s ~/.local/bin ~/bin`. - ### Install pip Install `pip` from the system package manager: ```sh -sudo apt install python3-pip # Ubuntu -sudo pkg py38-pip # FreeBSD +sudo pkg install py38-pip # FreeBSD +sudo apt install python3-pip # Linux (Ubuntu) sudo port install py39-pip # MacOS ``` -Then run `python3 -m pip install -U pip` to install latest version into your -user account under `~/.local/bin`. In the end you should be able to run `pip --version` and `python3 -c "import sqlite3"` without errors. -In some systems, `pip` can be named `pip3`, `pip3.8` or `pip-3.8`. +In some systems, `pip` can be named `pip3`, `pip3.8` or `pip-3.8`, etc. -Edit the configuration file `~/.config/pip/pip.conf` (FreeBSD, Linux) or +Packages should **not** be installed system-wide. To install locally in the user +area, edit the configuration file `~/.config/pip/pip.conf` (FreeBSD, Linux) or `Library/Application Support/pip/pip.conf` (MacOS) and add the lines ```ini @@ -84,30 +53,22 @@ Edit the configuration file `~/.config/pip/pip.conf` (FreeBSD, Linux) or user = yes ``` -This will set pip to install modules in the user area (recommended). - -### Download and install aprendizations +### Install aprendizations ```sh -git clone https://git.xdi.uevora.pt/mjsb/aprendizations.git -cd aprendizations -npm install # install javascript libraries -pip install . # install aprendizations and dependencies +pip install git+https://git.xdi.uevora.pt/mjsb/aprendizations.git ``` -Javascript libraries are installed in `aprendizations/node_modules` and are -linked from `aprendizations/aprendizations/static`. - Python packages are usually installed in: * `~/.local/lib/python3.8/site-packages/` in Linux/FreeBSD. * `~/Library/python/3.9/lib/python/site-packages/` in MacOS. When aprendizations is installed with pip, all the dependencies are also -installed. The javascript libraries previously installed with npm are copied to -the above directory and the cloned repository is no longer needed. +installed. -At this point `aprendizations` is installed in +At this point, the commands `aprendizations` and `initdb-aprendizations` are +installed in ```sh ~/.local/bin # Linux/FreeBSD @@ -119,6 +80,7 @@ and can be run from the terminal: ```sh aprendizations --version aprendizations --help +initdb-aprendizations --help ``` ### SSL Certificates @@ -172,7 +134,7 @@ chmod 400 cert.pem privkey.pem User data is maintained in a sqlite3 database which has to be created manually using the `initdb-aprendizations` command. The database file should be located -in the same directory as the main YAML configuration file. +in the same directory as the main YAML configuration file (`courses.yaml`). For example, to run the included demo do: @@ -190,12 +152,12 @@ The default password is equal to the user name, if left undefined. ### Running the demo -The application includes a small example in `demo/demo.yaml` that can be used +The application includes a small example in `demo/courses.yaml` that can be used for initial testing. Run it with ```sh cd demo -aprendizations demo.yaml +aprendizations courses.yaml ``` Open the browser at [https://127.0.0.1:8443](https://127.0.0.1:8443). @@ -237,28 +199,25 @@ pflog_logfile="/var/log/pflog" Reboot or `sudo service pf start`. +Example configuration files are in the `freebsd` directory. + ### Testing the system Make sure the following steps have been done: -* installed python3, pip and npm -* git-cloned the aprendizations from the main repository -* installed javascript libraries with npm -* installed aprendizations with pip +* installed python3 and pip +* installed aprendizations using pip * initialized database with at least 1 user * generate and copy certificates to the appropriate place * (optional) configure the firewall to do port forwarding -* run `aprendizations demo.yaml --check` +* run `aprendizations courses.yaml --check` ## Keeping aprendizations updated To update aprendizations to the latest version do: ```sh -cd aprendizations -git pull # get latest version -npm update # update javascript libraries -pip install -U . # updates installed version +pip install -U git+https://git.xdi.uevora.pt/mjsb/aprendizations.git ``` ## Troubleshooting @@ -304,20 +263,6 @@ To fix this issue you need to allow animations in the Operating System: * On MacOS or iOS search for reduced motion and switch it **OFF** (Preferences -> Acessibility -> Display -> Reduce motion). -### The application runs but questions do not show up - -Some operating systems have an option to disable animations to try to avoid -motion sickness in some people. Browsers will check this option with the OS and -prevent animate.css library to work. Since questions have several animations, -these will will not work and nothing is shown on the page. - -To fix this issue you need to allow animations in the Operating System: - -* On windows 10, go to System Preferences, search for "Show animations in - windows" and turn it **ON**. -* On MacOS or iOS search for reduced motion and switch it **OFF** - (Preferences -> Acessibility -> Display -> Reduce motion). - ## FAQ Common database manipulations: diff --git a/aprendizations/__init__.py b/aprendizations/__init__.py index 0881ff1..e1a3f7b 100644 --- a/aprendizations/__init__.py +++ b/aprendizations/__init__.py @@ -30,7 +30,7 @@ are progressively uncovered as the students progress. ''' APP_NAME = 'aprendizations' -APP_VERSION = '2021.08.dev1' +APP_VERSION = '2021.11.dev1' APP_DESCRIPTION = __doc__ __author__ = 'Miguel Barão' diff --git a/aprendizations/learnapp.py b/aprendizations/learnapp.py index c526532..9d4b978 100644 --- a/aprendizations/learnapp.py +++ b/aprendizations/learnapp.py @@ -86,7 +86,7 @@ class LearnApp(): for course_file in config.get('topics_from', []): course_conf = load_yaml(course_file) # course configuration # FIXME set defaults?? - logger.info('%6d topics imported from %s', + logger.info('%6d topics from %s', len(course_conf["topics"]), course_file) self._populate_graph(course_conf) logger.info('Graph has %d topics', len(self.deps)) @@ -327,7 +327,7 @@ class LearnApp(): logger.warning('"%s" could not start course "%s"', uid, course_id) raise LearnException() from exc else: - logger.info('User "%s" started course "%s"', uid, course_id) + logger.info('User "%s" course "%s"', uid, course_id) # ------------------------------------------------------------------------ # @@ -609,15 +609,17 @@ class LearnApp(): This should be modified to have a "visible" flag ''' - logger.info('User "%s" get rankings for %s', uid, course_id) - query_students = select(Student.id, Student.name) - query_student_topics = select(StudentTopic.student_id, - StudentTopic.topic_id, - StudentTopic.level, - StudentTopic.date) - query_total = select(Answer.student_id, func.count(Answer.ref)) - query_right = select(Answer.student_id, func.count(Answer.ref)).where(Answer.grade == 1.0) + logger.info('User "%s" rankings for "%s"', uid, course_id) with Session(self._engine, future=True) as session: + query_students = select(Student.id, Student.name) + query_student_topics = select(StudentTopic.student_id, + StudentTopic.topic_id, + StudentTopic.level, + StudentTopic.date) + query_total = select(Answer.student_id, func.count(Answer.ref)) + query_right = select(Answer.student_id, func.count(Answer.ref)) \ + .where(Answer.grade == 1.0) + # all students in the database FIXME only with answers of this course students = session.execute(query_students).all() @@ -625,6 +627,9 @@ class LearnApp(): student_topics = session.execute(query_student_topics).all() # answer performance + + # FIXME this does not work when nobody has done anything... + # FIXME row to dict seems to be deprecated in 1.4+ total = dict(session.execute(query_total).all()) right = dict(session.execute(query_right).all()) diff --git a/aprendizations/static/codemirror b/aprendizations/static/codemirror deleted file mode 120000 index de58ef1..0000000 --- a/aprendizations/static/codemirror +++ /dev/null @@ -1 +0,0 @@ -../../node_modules/codemirror/ \ No newline at end of file diff --git a/aprendizations/static/fontawesome-free b/aprendizations/static/fontawesome-free deleted file mode 120000 index 50141d7..0000000 --- a/aprendizations/static/fontawesome-free +++ /dev/null @@ -1 +0,0 @@ -../../node_modules/@fortawesome/fontawesome-free/ \ No newline at end of file diff --git a/aprendizations/templates/courses.html b/aprendizations/templates/courses.html index 1aee6cf..a79b595 100644 --- a/aprendizations/templates/courses.html +++ b/aprendizations/templates/courses.html @@ -9,14 +9,16 @@ + - + + - - {{appname}} diff --git a/aprendizations/templates/maintopics-table.html b/aprendizations/templates/maintopics-table.html index 1a50cd0..af888fe 100644 --- a/aprendizations/templates/maintopics-table.html +++ b/aprendizations/templates/maintopics-table.html @@ -10,6 +10,7 @@ + @@ -17,7 +18,6 @@ - {{appname}} diff --git a/aprendizations/templates/rankings.html b/aprendizations/templates/rankings.html index 1c049df..a597259 100644 --- a/aprendizations/templates/rankings.html +++ b/aprendizations/templates/rankings.html @@ -9,10 +9,12 @@ + + - + {{appname}} diff --git a/aprendizations/templates/topic.html b/aprendizations/templates/topic.html index 32ebe07..856cdd4 100644 --- a/aprendizations/templates/topic.html +++ b/aprendizations/templates/topic.html @@ -6,16 +6,17 @@ - - - + + + + + + + - - - - - + - + + + - - - - - - + {{appname}} diff --git a/freebsd/pf.conf b/freebsd/pf.conf new file mode 100644 index 0000000..5248a8d --- /dev/null +++ b/freebsd/pf.conf @@ -0,0 +1,60 @@ + +# Public interface +ext_if="em0" + +table persist + +# Set and drop these IP ranges on public interface +martians = "{ 0.0.0.0/8, 127.0.0.0/8 }" + +# 192.168.0.0/16, 172.16.0.0/12, \ +# 10.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24, \ +# 240.0.0.0/4 }" + +webports = "{ 8080, 8443 }" + +tcp_services = "{ domain, ntp, smtp, www, https, ssh }" +udp_services = "{ domain, ntp }" + +# Skip all PF processing on loopback interface +set skip on lo + +# Log statistics on interface +set loginterface $ext_if + +# Packet normalization +scrub in all + +# Redirect http and https ports to 8080 and 8443, resp. +no rdr on $ext_if proto tcp from to any +rdr on $ext_if proto tcp from any to any port 80 -> 127.0.0.1 port 8080 +rdr on $ext_if proto tcp from any to any port 443 -> 127.0.0.1 port 8443 + +# Default policy +#block return in log all +#block out all + +# Protect against spoofed or forget IP addresses +antispoof quick for $ext_if + +# Drop all Non-Routable Addresses +block drop in quick on $ext_if from $martians to any +block drop out quick on $ext_if from any to $martians + +# Protect against SSH attacks +block quick from +pass quick proto { tcp, udp } from any to any port ssh \ + flags S/SA keep state \ + (max-src-conn 10, max-src-conn-rate 5/3, \ + overload flush global) + +# Allow Ping +pass inet proto icmp icmp-type echoreq + +# Webserver +#pass proto tcp from any to $ext_if port $webports + +# Allow essential outgoing traffic +pass out quick on $ext_if proto tcp to any port $tcp_services +pass out quick on $ext_if proto udp to any port $udp_services + diff --git a/freebsd/rc.conf b/freebsd/rc.conf new file mode 100644 index 0000000..eca64f6 --- /dev/null +++ b/freebsd/rc.conf @@ -0,0 +1,21 @@ +zfs_enable="YES" +clear_tmp_enable="YES" +hostname="bit.xdi.uevora.pt" +ifconfig_em0="inet 193.137.120.198 netmask 255.255.255.192" +defaultrouter="193.137.120.254" +ifconfig_em0_ipv6="inet6 accept_rtadv" +sshd_enable="YES" +ntpd_enable="YES" +ntpd_sync_on_start="YES" +powerd_enable="NO" + +# pf firewall +pf_enable="YES" +#pf_flags="-T expire 86400" +pf_rules="/etc/pf.conf" +#pflog_enable="YES" +#pflog_flags="" +#pflog_logfile="/var/log/pflog" + +# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable +dumpdev="NO" diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 3192aae..0000000 --- a/package-lock.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "aprendizations", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "dependencies": { - "@fortawesome/fontawesome-free": "^5.15.3", - "codemirror": "^5.59.4" - } - }, - "node_modules/@fortawesome/fontawesome-free": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", - "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==", - "hasInstallScript": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/codemirror": { - "version": "5.63.3", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.63.3.tgz", - "integrity": "sha512-1C+LELr+5grgJYqwZKqxrcbPsHFHapVaVAloBsFBASbpLnQqLw1U8yXJ3gT5D+rhxIiSpo+kTqN+hQ+9ialIXw==" - } - }, - "dependencies": { - "@fortawesome/fontawesome-free": { - "version": "5.15.4", - "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz", - "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==" - }, - "codemirror": { - "version": "5.63.3", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.63.3.tgz", - "integrity": "sha512-1C+LELr+5grgJYqwZKqxrcbPsHFHapVaVAloBsFBASbpLnQqLw1U8yXJ3gT5D+rhxIiSpo+kTqN+hQ+9ialIXw==" - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index b4b1992..0000000 --- a/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "description": "Javascript libraries required to run the server", - "email": "mjsb@uevora.pt", - "dependencies": { - "@fortawesome/fontawesome-free": "^5.15.3", - "codemirror": "^5.59.4" - }, - "private": true -} -- libgit2 0.21.2