Make ssl redirection a separate config
[oweals/karmaworld.git] / README.md
1 # KarmaWorld
2 __Description__: A django application for sharing and uploading class notes.
3
4 __Copyright__: FinalsClub, a 501c3 non-profit organization
5
6 __License__: GPLv3 except where otherwise noted
7
8 __Contact__: info@karmanotes.org
9
10 v3.0 of the karmanotes.org website from the FinalsClub Foundation
11
12 # Purpose
13
14 KarmaNotes is an online database of college lecture notes.  KarmaNotes empowers college students to participate in the free exchange of knowledge. 
15
16 # Pre-Installation
17
18 ## Code
19
20 Before doing anything, you'll need the code. Grab it from github.
21
22 Clone the project from the central repo using your github account:
23
24     git clone git@github.com:FinalsClub/karmaworld.git
25
26 If you aren't using a system setup for github, then grab the project with
27 this command instead:
28
29     git clone https://github.com/FinalsClub/karmaworld.git
30
31 Generally speaking, this will create a subdirectory called `karmaworld` under
32 the directory where the `git` command was run. This git repository directory
33 will be referred to herein as `{project_root}`.
34
35 There might be some confusion as the git repository's directory will likely be
36 called `karmaworld` (this is `{project_root}`), but there is also a `karmaworld`
37 directory underneath that (`{project_root}/karmaworld`) alongside files like
38 `fabfile.py` (`{project_root}/fabfile.py`) and `README.md`
39 (`{project_root}/README.md`).
40
41 ## External Service Dependencies
42
43 Notice: This software makes use of external third party services which require
44 accounts to access the service APIs. Without these third parties available,
45 this software may require considerable overhaul. These services have
46 API keys, credentials, and other information that you must provide to KarmaNotes
47 as environment variables. The best way to persist these environment variables is
48 by using a `.env` file. Copy `.env.example` to `.env` and populate the fields as
49 required.
50
51 ### Heroku
52 This project has chosen to use [Heroku](www.heroku.com) to host the Django and
53 celery software. While not a hard requirement, the more up-to-date parts of this
54 documentation will operate assuming Heroku is in use.
55
56 See README.heroku for more information.
57
58 ### Amazon S3
59 The instructions for creating an [S3](http://aws.amazon.com/s3/) bucket may be
60 [found on Amazon.](http://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html)
61
62 Two, separate buckets will be needed in production: one for static file hosting
63 and one as a communication bus with Filepicker.
64
65 This software uses S3 to store files which are sent to or received 
66 from Filepicker. Filepicker will need to know the S3 bucket name, access key,
67 and secret key.
68
69 Filepicker users can only make use of an S3 bucket with a paid account. For
70 development purposes, no Filepicker S3 bucket is needed. Skip all references to
71 the Filepicker S3 bucket in the development case.
72
73 The software will not need to know the S3 credentials for the Filepicker
74 bucket, because the software will upload files to the Filepicker S3 bucket
75 through Filepicker's API and it will link to or download files from the
76 Filepicker S3 bucket through Filepicker's URLs. This will be covered in the
77 Filepicker section below.
78
79 This software uses S3 for hosting static files. The software will need to
80 update static files on the S3 bucket. As such, the software will need the
81 S3 bucket name, access key, and secret key via the environment variables. This
82 is described in subsections below.
83
84 To support static hosting, `DEFAULT_FILE_STORAGE` should be set to
85 `'storages.backends.s3boto.S3BotoStorage'`, unless there is a compelling reason
86 to change it.
87
88 There are three ways to setup access to the S3 buckets depending upon speed
89 and security. The more secure, the slower it will be to setup.
90
91 #### insecure S3 access
92 For quick and dirty insecure S3 access, create a single group and a single user
93 with full access to all buckets. Full access to all buckets is insecure!
94
95 Create an 
96 [Amazon IAM group](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_CreatingAndListingGroups.html)
97 with full access to the S3 bucket. Select the "Amazon S3 Full Accesss" Policy
98 Template.
99
100 Create an
101 [Amazon IAM user](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_SettingUpUser.html).
102 Copy the credentials into the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
103 environment variables. Be sure to write down the access information, as it
104 will only be shown once.
105
106 #### secure S3 access
107 For secure S3 access, two users will be needed. One with access to the
108 Filepicker bucket and one with access to the static hosting bucket.
109
110 Note: this might need to be modified to prevent creation and deletion of
111 buckets?
112
113 Create an 
114 [Amazon IAM group](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_CreatingAndListingGroups.html)
115 with full access to the S3 bucket. The quick way is to select the
116 "Amazon S3 Full Accesss" Policy Template and replace `"Resource": "*"` with 
117 `"Resource": "arn:aws:s3:::<static_bucket_name>"`.
118
119 Create an
120 [Amazon IAM user](http://docs.aws.amazon.com/IAM/latest/UserGuide/Using_SettingUpUser.html).
121 Copy the credentials into the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`
122 environment variables. Be sure to write down the access information, as it
123 will only be shown once.
124
125 Ensure the created user is a member of the group with access to the S3
126 static files bucket.
127
128 Repeat the process again, creating a group for the Filepicker bucket and
129 creating a user with access to that group. These credentials will be passed
130 on to Filepicker.
131
132 #### somewhat secure S3 access
133 Create two groups as described in the `secure S3 access` section above.
134
135 Create a single user, save the credentials as described in the
136 `insecure S3 access` section above, and pass the credentials on to Filepicker.
137
138 Add the single user to both groups.
139
140 This is less secure because if your web server or Filepicker get compromised
141 (so there are two points for potential failure), the single compromised
142 user has full access to both buckets.
143
144 ### Amazon Cloudfront CDN
145 [Cloudfront CDN](http://aws.amazon.com/cloudfront/) assists static file hosting.
146
147 Follow
148 [Amazon's instructions](http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.html)
149 to host static files out of the appropriate S3 bucket. Note that Django's static
150 file upload process has been modified to mark static files as publicly
151 assessible.
152
153 In the settings for the Cloudfront Distribution, copy the "Domain Name" from
154 General settings and set `CLOUDFRONT_DOMAIN` to it. For example, `abcdefghij.cloudfront.net`.
155
156 ### Amazon Mechanical Turk
157 Mechanical turk is employed to generate human feedback from uploaded notes.
158 This service is helpful for generating flash cards and quizzes.
159
160 This service is optional and it might cause unexpected charges when
161 deployed.  If the required environment variable is not found,
162 then no errors will occur and no mechanical turk tasks will be created, avoiding any unexpected
163 costs.
164
165 The `MTURK_HOST` environment variable is almost certainly
166 `"mechanicalturk.amazonaws.com"`.
167
168 The code will create and publish HITs on your behalf.
169
170 ### Google Drive
171 This software uses [Google Drive](https://developers.google.com/drive/) to
172 convert documents to and from various file formats.
173
174 A Google Drive service account with access to the Google Drive is required.
175 This may be done with a Google Apps account with administrative privileges, or ask
176 your business sysadmin.
177
178 Follow [Google's instructions](https://developers.google.com/drive/delegation)
179 to create a Google Drive service account.
180
181 Convert the p12 file into a Base64 encoded string for the
182 `GOOGLE_SERVICE_KEY_BASE64` environment variable. There are many ways to do
183 this. If Python is available, the
184 [binascii library](https://docs.python.org/2/library/binascii.html#binascii.b2a_base64)
185 makes this very easy:
186
187         import binascii
188         with open('file.p12', 'r') as f:
189             print binascii.b2a_base64(f.read)
190
191 Copy the contents of `client_secret_*.apps.googleusercontent.com.json` into the
192 `GOOGLE_CLIENT_SECRETS` environment variable.
193
194 ### Filepicker
195 This software uses [Filepicker.io](https://www.inkfilepicker.com/) for uploading
196 files. This requires an account with Filepicker.
197
198 Filepicker can use an additional third party file hosting site where it may
199 send uploaded files. This project, in production, uses Amazon S3 as the third
200 party. See the Amazon S3 section above for more information.  
201
202 Create a new App with Web SDK and provide the Heroku App URL for the
203 Application's URL. You'll be given an API Key for the App. Paste this into the
204 `FILEPICKER_API_KEY` environment variable.
205
206 Find the 'App Security' button on the left hand side of the web site. Make sure
207 'Use Security' is enabled. Generate a new secret key. Paste this key into the
208 `FILEPICKER_SECRET` environment variable.
209
210 If you have an upgraded plan, you can configure Filepicker to have access to
211 your Filepicker S3 bucket. Click 'Amazon S3' on the left hand side menu and
212 supply the credentials for the user with access to the Filepicker S3 bucket.
213
214 ### IndexDen
215 KarmaNotes uses IndexDen to create a searchable index of all the notes in the
216 system. Create an free IndexDen account at
217 [their homepage](http://indexden.com/). You will be given a private URL that
218 accesses your IndexDen account. This URL is visible on your dashboard (you
219 might need to scroll down).
220
221 Set the `INDEXDEN_PRIVATE_URL` environment variable to your private URL.
222
223 Set the `INDEXDEN_INDEX` environment variable to the name of the index you want
224 to use for KarmaNotes. The index will be created automatically when KarmaNotes
225 is run if it doesn't already exist. It may be created through the GUI if
226 desired.
227
228 ### Twitter
229
230 Twitter is used to post updates about new courses. Access to the Twitter API
231 will be required for this task.
232
233 If this Twitter feature is desired, the consumer key and secret as well as the
234 access token key and secret are needed by the software.
235
236 If the required environment variables are not found, then no errors will occur
237 and no tweets will be posted.
238
239 To set this up,
240 [create a new Twitter application](https://dev.twitter.com/apps/new).
241 Use your Heroku App URL for the website field. Leave the Callback field blank.
242
243 Make sure this application has read/write access. Generate an access token. Go
244 to your OAuth settings, and grab the "Consumer key", "Consumer secret",
245 "Access token", and "Access token secret". Paste these, respectively, into the
246 environment variables `TWITTER_CONSUMER_KEY`, `TWITTER_CONSUMER_SECRET`,
247 `TWITTER_ACCESS_TOKEN_KEY`, `TWITTER_ACCESS_TOKEN_SECRET`.
248
249 ### SSL Certificate
250
251 If you wish to host your system publicly, you'll need an SSL certificate
252 signed by a proper authority.
253
254 Follow [Heroku's SSL setup](https://devcenter.heroku.com/articles/ssl-endpoint)
255 to get SSL running on your server.
256
257 You may set the `SSL_REDIRECT` environment variable to `true` to make KarmaNotes
258 redirect insecure connections to secure ones.
259
260 # Local Install
261
262 KarmaNotes is a Heroku application. Download the [Heroku toolbelt](https://toolbelt.heroku.com/).
263
264 Before your running it for the first time, there are
265 a few setup steps:
266   1. `virtualenv venv`
267   1. `source venv/bin/activate`
268   1. `pip install -r requirements.txt`
269   1. `pip install -r requirements-dev.txt`
270   1. `foreman run python manage.py syncdb --migrate --noinput`
271   1. `foreman run python manage.py createsuperuser`
272   1. `foreman run python manage.py fetch_usde_csv ./schools.csv`
273   1. `foreman run python manage.py import_usde _csv ./schools.csv`
274   1. `foreman run python manage.py sanitize_usde_schools`
275
276 To run KarmaNotes locally, make sure you are inside your
277 virtual environment (`source venv/bin/activate`) and run `foreman start`.
278 Press ctrl-C to kill foreman. Foreman will run Django's runserver command.
279 If you wish to have more control over how this is done, you can do
280 `foreman run python manage.py runserver <options>`. For running any other
281 `manage.py` commands, you should also precede them with `foreman run` like just shown.
282 This simply ensures that the environment variables from `.env` are present.
283
284 # Heroku Install
285
286 KarmaNotes is a Heroku application. Download the [Heroku toolbelt](https://toolbelt.heroku.com/).
287
288 To run KarmaNotes on Heroku, do `heroku create` and `git push heroku master` as typical
289 for a Heroku application. Set your the variable `BUILDPACK_URL` to
290 `https://github.com/charlesconnell/heroku-buildpack-karmanotes` to use a buildpack designed
291 to support KarmaNotes.
292
293 You will need to import the US Department of Education's list of accredited schools.
294    1. Fetch USDE schools with
295       `heroku run python manage.py fetch_usde_csv ./schools.csv`
296    1. Upload the schools into the database with
297       `heroku run python /manage.py import_usde _csv ./schools.csv`
298    1. Clean up redundant information with
299       `heroku run python /manage.py sanitize_usde_schools`
300
301
302 # Django Database management
303
304 ## South
305
306 We have setup Django to use
307 [south](http://south.aeracode.org/wiki/QuickStartGuide) for migrations. When
308 changing models, it is important to run
309 `foreman run python manage.py schemamigration` which will create a migration
310  to reflect the model changes into the database. These changes can be pulled
311 into the database with `foreman run python manage.py migrate`.
312
313 Sometimes the database already has a migration performed on it, but that
314 information wasn't told to south. There are subtleties to the process which
315 require looking at the south docs. As a tip, start by looking at the `--fake`
316 flag.
317
318 # Assets from Third Parties
319
320 A number of assets have been added to the repository which come from external
321 sources. It would be difficult to keep a complete list in this README and keep
322 it up to date. Software which originally came from outside parties can
323 generally be found in `karmaworld/assets`.
324
325 Additionally, all third party Python projects (downloaded and installed with
326 pip) are listed in these files:
327
328 * `requirements.txt`
329 * `requirements-dev.txt`
330
331 # Thanks
332
333 * KarmaNotes.org is a project of the FinalsClub Foundation with generous funding from the William and Flora Hewlett Foundation
334
335 * Also thanks to [rdegges](https://github.com/rdegges/django-skel) for the django-skel template