Skip to content

Commit b22be4d

Browse files
committed
initial code check-in (non-functional) based on old-PrairieLearn commit a4becba596bbaad6393a68bdb619487069991233
0 parents  commit b22be4d

File tree

146 files changed

+54647
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

146 files changed

+54647
-0
lines changed

README.md

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
2+
PrairieLearn
3+
============
4+
5+
PrairieLearn is an online problem-driven learning system. It consists
6+
of a server component that presents questions and other data via an
7+
API, and a webapp that interfaces with the user and communicates with
8+
the server.
9+
10+
Building
11+
--------
12+
13+
1. Install the pre-requisites:
14+
15+
* [Node.js](http://nodejs.org/)
16+
* [npm](https://npmjs.org/)
17+
* [MongoDB](http://www.mongodb.org/)
18+
19+
On OS X these can be installed with [MacPorts](http://www.macports.org/) or [Homebrew](http://brew.sh/).
20+
21+
2. Next clone the latest code:
22+
23+
$ git clone https://github.com/PrairieLearn/PrairieLearn.git
24+
25+
3. Install the backend libraries:
26+
27+
$ cd PrairieLearn/backend
28+
$ npm install
29+
30+
4. (Optional) Render question TeX image files for figures
31+
32+
$ cd PrairieLearn/backend
33+
$ make
34+
35+
36+
Running the server
37+
------------------
38+
39+
1. Run the database:
40+
41+
$ mongod --dbpath ~/db
42+
43+
2. Run the server:
44+
45+
$ cd PrairieLearn/backend
46+
$ node server
47+
48+
3. In a web-browswer view the PrairieLearn/frontend/index.html file:
49+
50+
$ open file://...<path>.../PrairieLearn/frontend/index.html
51+
52+
53+
To test the database, you can access it directly:
54+
55+
$ mongo
56+
> show dbs
57+
> use data
58+
> show collections
59+
> db.users.find()
60+
> db.users.save({uid: "user1@illinois.edu"})
61+
62+
To test the server, you can access it from the commandline:
63+
64+
$ curl http://localhost:3000/questions
65+
$ curl http://localhost:3000/questions/scalarAdd
66+
67+
$ curl -H "X-Auth-UID: user1@illinois.edu" -H "X-Auth-Name: User Name" -H "X-Auth-Date: 2013-08-17T09:44:18Z" -H "X-Auth-Signature: 3d38a7acba63047cf8bcf29f9691c68a2cae30e3ae5057ef1ea4616d2060a4be" http://localhost:3000/users
68+
$ curl -H "X-Auth-UID: user1@illinois.edu" -H "X-Auth-Name: User Name" -H "X-Auth-Date: 2013-08-17T09:44:18Z" -H "X-Auth-Signature: 3d38a7acba63047cf8bcf29f9691c68a2cae30e3ae5057ef1ea4616d2060a4be" http://localhost:3000/users/user1@illinois.edu
69+
70+
$ curl -H "X-Auth-UID: user1@illinois.edu" -H "X-Auth-Name: User Name" -H "X-Auth-Date: 2013-08-17T09:44:18Z" -H "X-Auth-Signature: 3d38a7acba63047cf8bcf29f9691c68a2cae30e3ae5057ef1ea4616d2060a4be" -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"uid": "user1@illinois.edu", "qid": "scalarAdd"}' http://localhost:3000/qInstances
71+
72+
$ curl http://localhost:3000/questions/scalarAdd/1/question.html
73+
$ curl http://localhost:3000/questions/scalarAdd/1/client.js
74+
$ curl http://localhost:3000/questions/scalarAdd/1/params
75+
76+
$ curl -H "X-Auth-UID: user1@illinois.edu" -H "X-Auth-Name: User Name" -H "X-Auth-Date: 2013-08-17T09:44:18Z" -H "X-Auth-Signature: 3d38a7acba63047cf8bcf29f9691c68a2cae30e3ae5057ef1ea4616d2060a4be" -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"uid": "user1@illinois.edu", "qid": "scalarAdd", "vid": "1", "qiid": "qi32", "submittedAnswer": {"c": "43"}}' http://localhost:3000/submissions
77+
78+
Useful curl options:
79+
80+
--trace
81+
--trace-time
82+
-w, --write-out
83+
-v, --verbose
84+
85+
86+
Accessing the client
87+
--------------------
88+
89+
To access the client we can either run a webserver locally or acess
90+
the files directly from disk.
91+
92+
### Accessing files directly from disk
93+
94+
Simply open `frontend/index.html` in a web browser. Chrome will give
95+
cross-origin errors when loading non-javascript from disk, so it must
96+
be run with the `--allow-file-access-from-files` commandline
97+
argument. Under OS X this can be done with:
98+
99+
open '/Applications/Google Chrome.app' --new --args --allow-file-access-from-files
100+
101+
On Windows this can be done by adding the
102+
`--allow-file-access-from-files` flag to a special shortcut (edit it
103+
with right-click and properties -> target).
104+
105+
To disable cross-origin errors in Firefox go to `about:config` and set
106+
`security.fileuri.strict_origin_policy` to `false`.
107+
108+
### Run a local webserver
109+
110+
Any webserver that can serve up the `frontend` directory tree can be
111+
used to access the client. One particularly easy way to do this is to
112+
run `python -m SimpleHTTPServer` in the `frontend` directory, and then
113+
point the webbrowser to `http://localhost:8000`.
114+
115+
116+
Restore of the database
117+
----------------------------------
118+
119+
When the DB is stopped:
120+
121+
mongorestore --dbpath ~/db ~/path-to-dump
122+
123+
124+
Miscellaneous Notes
125+
===================
126+
127+
### Run grunt to check code
128+
129+
$ sudo npm install -g grunt-cli
130+
$ grunt
131+
132+
### Use `marked` to process markdown
133+
134+
$ sudo npm install -g marked
135+
$ marked --gfm README.md > README.html
136+
137+
138+
Tools and libraries
139+
===================
140+
141+
* [Node.js](http://nodejs.org/)
142+
* [npm](https://npmjs.org/)
143+
* [MongoDB](http://www.mongodb.org/)
144+
* [Express](http://expressjs.com/)
145+
* [jQuery](http://jquery.com/)
146+
* [Underscore.js](http://underscorejs.org/)
147+
* [Backbone.js](http://backbonejs.org/)
148+
* [Bootstrap](http://getbootstrap.com/)
149+
* [Grunt](http://gruntjs.com/)
150+
* [async](https://github.com/caolan/async)
151+
* [JSHint](http://www.jshint.com/)
152+
* [RequireJS](http://requirejs.org/)
153+
* [tween.js](https://github.com/sole/tween.js/)
154+
* [Sylvester](http://sylvester.jcoglan.com/)
155+
* [MathJax](http://www.mathjax.org/)
156+
* [Rivets.js](http://rivetsjs.com/)
157+
158+
159+
Deploying to a Vagrant virtual machine
160+
======================================
161+
162+
Install:
163+
164+
* VirtualBox: http://www.virtualbox.org/
165+
* Vagrant: http://www.vagrantup.com/
166+
167+
In the `PrairieLearn` directory run:
168+
169+
vagrant up # download and boot the VM and install packages
170+
171+
To run the PrairieLearn server do:
172+
173+
vagrant ssh # login to the VM
174+
cd /vagrant/backend # change to the PrairieLearn backend server directory
175+
npm install # install libary packages (one time only)
176+
make # compile latex in figures (only after changing figure latex)
177+
grunt # check code for syntax and style (optional)
178+
node server # run the PrairieLearn server
179+
180+
When the server is running, access PrairieLearn in a web browser on
181+
the host at the URL http://localhost:8080/
182+
183+
To stop the server and logout of the VM:
184+
185+
ctrl-c # stop the server
186+
logout # logout of the VM (can also use ctrl-d)
187+
188+
Other useful vagrant commands on the host:
189+
190+
vagrant halt # shutdown the VM
191+
vagrant destroy # delete the VM completely
192+
vagrant up # start the VM again (after halt or destroy)
193+
vagrant suspend # suspend the VM
194+
vagrant resume # resume a suspended VM

Vagrantfile

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# -*- mode: ruby -*-
2+
# vi: set ft=ruby :
3+
4+
$script = <<SCRIPT
5+
6+
echo Disabling selinux...
7+
setenforce 0 | /bin/true # turn off selinux
8+
#perl -pi -e 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
9+
10+
echo Disabling firewall...
11+
chkconfig iptables off
12+
service iptables stop
13+
14+
echo Installing EPEL repository...
15+
rpm -i http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
16+
17+
echo Installing MongoDB...
18+
yum -y install mongodb-server
19+
yum -y install mongodb
20+
21+
echo Starting MongoDB...
22+
chkconfig mongod on
23+
service mongod start
24+
25+
echo Installing NodeJS...
26+
yum -y install nodejs
27+
yum -y install npm
28+
npm install -g grunt-cli
29+
30+
echo Installing LaTeX...
31+
yum -y install texlive-latex
32+
yum -y install ImageMagick
33+
34+
echo Installing Apache...
35+
yum -y install httpd
36+
37+
echo Point Apache to the frontend files...
38+
rmdir /var/www/html
39+
ln -s /vagrant/frontend /var/www/html
40+
41+
echo Starting Apache...
42+
chkconfig httpd on
43+
service httpd start
44+
45+
SCRIPT
46+
47+
Vagrant.configure("2") do |config|
48+
config.vm.box = "centos64"
49+
config.vm.box_url = "http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210.box"
50+
config.vm.network :forwarded_port, guest: 3000, host: 3000
51+
config.vm.network :forwarded_port, guest: 80, host: 8080
52+
config.vm.provision :shell, :inline => $script
53+
end

auth/Makefile

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
auth: auth.o hmac.o sha2.o
3+
gcc -o $@ $^
4+
5+
auth.o: auth.c
6+
gcc -c -o $@ $<
7+
8+
hmac.o: hmac/hmac_sha2.c hmac/hmac_sha2.h
9+
gcc -c -o $@ $<
10+
11+
sha2.o: hmac/sha2.c hmac/sha2.h
12+
gcc -c -o $@ $<
13+
14+
clean:
15+
rm -f auth auth.o hmac.o sha2.o

auth/auth.c

+95
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
#include <stdlib.h>
2+
#include <stdio.h>
3+
#include <string.h>
4+
#include <time.h>
5+
#include "hmac/hmac_sha2.h" // https://github.com/ouah/hmac
6+
7+
// extern char **environ;
8+
9+
#define ENV_UID "eppn"
10+
#define ENV_NAME "displayName"
11+
12+
#define SHA256_HASH_SIZE 32
13+
#define SECRET_KEY "THIS_IS_THE_SECRET_KEY"
14+
15+
char *iso8601Now() {
16+
time_t current_time;
17+
struct tm *time_data;
18+
char *time_string;
19+
20+
if (!(time_string = malloc(26 * sizeof(char)))) {
21+
fprintf(stderr, "Error: unable to allocate time_string\n");
22+
exit(1);
23+
}
24+
current_time = time(NULL);
25+
time_data = localtime(&current_time);
26+
sprintf(time_string, "%04d-%02d-%02dT%02d:%02d:%02d%+03d:%02d",
27+
time_data->tm_year + 1900, time_data->tm_mon + 1, time_data->tm_mday,
28+
time_data->tm_hour, time_data->tm_min, time_data->tm_sec,
29+
time_data->tm_gmtoff / 3600, (abs(time_data->tm_gmtoff) % 3600) / 60);
30+
return time_string;
31+
}
32+
33+
char *sha256Signature(char *uid, char *name, char *date) {
34+
size_t msg_size, sig_size, i;
35+
char *msg;
36+
char hash[SHA256_HASH_SIZE];
37+
char *sig;
38+
39+
msg_size = strlen(uid) + strlen(name) + strlen(date) + 2;
40+
if (!(msg = malloc(msg_size * sizeof(char)))) {
41+
fprintf(stderr, "Error: unable to allocate msg\n");
42+
exit(1);
43+
}
44+
i = 0;
45+
strncpy(&msg[i], uid, strlen(uid));
46+
i += strlen(uid);
47+
msg[i++] = '/';
48+
strncpy(&msg[i], name, strlen(name));
49+
i += strlen(name);
50+
msg[i++] = '/';
51+
strncpy(&msg[i], date, strlen(date));
52+
53+
hmac_sha256(SECRET_KEY, strlen(SECRET_KEY), msg, msg_size, hash, SHA256_HASH_SIZE);
54+
55+
sig_size = 2 * SHA256_HASH_SIZE + 1;
56+
if (!(sig = malloc(sig_size * sizeof(char)))) {
57+
fprintf(stderr, "Error: unable to allocate sig\n");
58+
exit(1);
59+
}
60+
for (i = 0; i < SHA256_HASH_SIZE; i++) {
61+
sprintf(&sig[2 * i], "%02x", (unsigned char)hash[i]);
62+
}
63+
return sig;
64+
}
65+
66+
int main() {
67+
char *uid, *name;
68+
char *time_string;
69+
char *signature;
70+
// char **env;
71+
72+
if (!(uid = getenv(ENV_UID))) {
73+
fprintf(stderr, "Error: unable to get environment variable: %s\n", ENV_UID);
74+
exit(1);
75+
}
76+
if (!(name = getenv(ENV_NAME))) {
77+
fprintf(stderr, "Error: unable to get environment variable: %s\n", ENV_NAME);
78+
exit(1);
79+
}
80+
printf("Content-type: application/json\r\n\r\n");
81+
printf("{\n");
82+
printf(" \"uid\": \"%s\",\n", uid);
83+
printf(" \"name\": \"%s\",\n", name);
84+
time_string = iso8601Now();
85+
printf(" \"date\": \"%s\",\n", time_string);
86+
signature = sha256Signature(uid, name, time_string);
87+
printf(" \"signature\": \"%s\"\n", signature);
88+
printf("}\n");
89+
/*
90+
for (env = environ; *env; ++env) {
91+
printf("%s\r\n", *env);
92+
}
93+
*/
94+
return 0;
95+
}

auth/hmac/Makefile

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
all: hmac
2+
3+
hmac: hmac.o sha2.o
4+
$(CC) sha2.o hmac.o -o hmac
5+
6+
hmac.o: hmac_sha2.c hmac_sha2.h
7+
$(CC) -Wall -DTEST_VECTORS -c hmac_sha2.c -o hmac.o
8+
9+
sha2.o: sha2.c sha2.h
10+
$(CC) -c sha2.c -o sha2.o
11+
12+
clean:
13+
- rm -rf *.o hmac

0 commit comments

Comments
 (0)