{"action":"created","issue":{"url":"https://api.github.com/repos/RuddockHouse/RuddockWebsite/issues/65","labels_url":"https://api.github.com/repos/RuddockHouse/RuddockWebsite/issues/65/labels{/name}","comments_url":"https://api.github.com/repos/RuddockHouse/RuddockWebsite/issues/65/comments","events_url":"https://api.github.com/repos/RuddockHouse/RuddockWebsite/issues/65/events","html_url":"https://github.com/RuddockHouse/RuddockWebsite/pull/65","id":52460257,"number":65,"title":"Overhaul for website security/authentication","user":{"login":"dkong1796","id":1891237,"avatar_url":"https://avatars.githubusercontent.com/u/1891237?v=3","gravatar_id":"","url":"https://api.github.com/users/dkong1796","html_url":"https://github.com/dkong1796","followers_url":"https://api.github.com/users/dkong1796/followers","following_url":"https://api.github.com/users/dkong1796/following{/other_user}","gists_url":"https://api.github.com/users/dkong1796/gists{/gist_id}","starred_url":"https://api.github.com/users/dkong1796/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dkong1796/subscriptions","organizations_url":"https://api.github.com/users/dkong1796/orgs","repos_url":"https://api.github.com/users/dkong1796/repos","events_url":"https://api.github.com/users/dkong1796/events{/privacy}","received_events_url":"https://api.github.com/users/dkong1796/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":29,"created_at":"2014-12-19T08:49:41Z","updated_at":"2015-01-03T14:20:45Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/RuddockHouse/RuddockWebsite/pulls/65","html_url":"https://github.com/RuddockHouse/RuddockWebsite/pull/65","diff_url":"https://github.com/RuddockHouse/RuddockWebsite/pull/65.diff","patch_url":"https://github.com/RuddockHouse/RuddockWebsite/pull/65.patch"},"body":"- Password hashing with SHA-256 using PBKDF2_HMAC for key extension instead of single iteration MD5 (lol..)\r\n- Better password recovery with randomly generated keys, instead of using Python's built in hash function (which is completely unsuitable for cryptographic use), by storing the keys in the database\r\n- Legacy passwords are handled by storing information on how to hash them as part of the hash string:\r\n`$algorithm1|algorithm2|...|algorithmN$rounds1|...|roundsN$salt1|...|saltN$hash`\r\nAnd each algorithm is applied in turn to generate the hash. Upon successful authentication, the legacy password is automatically rehashed to the current algorithm. This makes it very easy to upgrade/change the hashing algorithm or number of rounds.\r\n- New script `migrate_passwords.py` can be used to rehash all the passwords with the current algorithm (currently they've only been hashed with MD5). It can be modified for future upgrades too.\r\n- Also (unrelated to everything else), created new `email_templates.py` which is where email templates belong, so we don't have massive blocks of text just sitting in the middle of the code.\r\n\r\nTested:\r\n- Login with invalid username does not work\r\n- Login with invalid password does not work\r\n- Login with correct credentials (with legacy hash) rehashes password to current algorithm.\r\n- Login with correct credentials (with current hash) works fine.\r\n- Password reset requires correct username/email combo\r\n- Password reset sends appropriate email to user with link for reset\r\n- Link for reset does expire after some time (currently set to 24 hours)\r\n- Reset password actually changes the password appropriately\r\n- Can add users as before, create account workflow also works as before.\r\n\r\nPlanned database changes (needs to be run BEFORE running the `migrate_passwords.py` script):\r\n```\r\nALTER TABLE users\r\nDROP COLUMN isactive;\r\n\r\nALTER TABLE users\r\nCHANGE COLUMN passwd password_hash VARCHAR(255) NOT NULL;\r\n\r\nALTER TABLE users\r\nADD COLUMN password_reset_key CHAR(32);\r\n\r\nALTER TABLE users\r\nADD COLUMN password_reset_expiration DATETIME;\r\n\r\nALTER TABLE users\r\nMODIFY COLUMN username VARCHAR(32) NOT NULL;\r\n\r\nALTER TABLE members\r\nADD COLUMN create_account_key CHAR(32);\r\n```\r\nThis is a one-time thing so I don't really want to include it in the repository, but it also can't happen until we're merging everything in. After running `migrate_passwords.py`, we can also drop the `salt` column."},"comment":{"url":"https://api.github.com/repos/RuddockHouse/RuddockWebsite/issues/comments/68596306","html_url":"https://github.com/RuddockHouse/RuddockWebsite/pull/65#issuecomment-68596306","issue_url":"https://api.github.com/repos/RuddockHouse/RuddockWebsite/issues/65","id":68596306,"user":{"login":"dkong1796","id":1891237,"avatar_url":"https://avatars.githubusercontent.com/u/1891237?v=3","gravatar_id":"","url":"https://api.github.com/users/dkong1796","html_url":"https://github.com/dkong1796","followers_url":"https://api.github.com/users/dkong1796/followers","following_url":"https://api.github.com/users/dkong1796/following{/other_user}","gists_url":"https://api.github.com/users/dkong1796/gists{/gist_id}","starred_url":"https://api.github.com/users/dkong1796/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dkong1796/subscriptions","organizations_url":"https://api.github.com/users/dkong1796/orgs","repos_url":"https://api.github.com/users/dkong1796/repos","events_url":"https://api.github.com/users/dkong1796/events{/privacy}","received_events_url":"https://api.github.com/users/dkong1796/received_events","type":"User","site_admin":false},"created_at":"2015-01-03T14:20:45Z","updated_at":"2015-01-03T14:20:45Z","body":"Yeah, I'm going to put account creation and also account management stuff (change username, change password) under /account. Also going to rewrite add members, so this isn't quite done yet."}}