{"action":"created","comment":{"url":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/comments/60849661","id":60849661,"diff_hunk":"@@ -132,23 +133,26 @@ def bool_int(value):\n     'GROWL_ON_EXTUP': (int, 'Growl', 0),\n     'GROWL_ON_INTUP': (int, 'Growl', 0),\n     'GROWL_ON_PMSUPDATE': (int, 'Growl', 0),\n+    'HOME_SECTIONS': (list, 'General', ['current_activity','watch_stats','library_stats','recently_added']),\n     'HOME_LIBRARY_CARDS': (list, 'General', ['first_run']),\n     'HOME_STATS_LENGTH': (int, 'General', 30),\n     'HOME_STATS_TYPE': (int, 'General', 0),\n     'HOME_STATS_COUNT': (int, 'General', 5),\n-    'HOME_STATS_CARDS': (list, 'General', ['top_tv', 'popular_tv', 'top_movies', 'popular_movies', 'top_music', \\\n+    'HOME_STATS_CARDS': (list, 'General', ['top_movies', 'popular_movies', 'top_tv', 'popular_tv', 'top_music', \\\n         'popular_music', 'last_watched', 'top_users', 'top_platforms', 'most_concurrent']),\n     'HTTPS_CREATE_CERT': (int, 'General', 1),\n     'HTTPS_CERT': (str, 'General', ''),\n     'HTTPS_KEY': (str, 'General', ''),\n     'HTTPS_DOMAIN': (str, 'General', 'localhost'),\n     'HTTPS_IP': (str, 'General', '127.0.0.1'),\n     'HTTP_ENVIRONMENT': (str, 'General', 'production'),\n+    'HTTP_HASH_PASSWORD': (int, 'General', 0),","path":"plexpy/config.py","position":26,"original_position":26,"commit_id":"a0d9726683df6574a733bffb54e482c3ebfcdc08","original_commit_id":"c82fec6683be71c115f959d7c7bff6f3403dd2ee","user":{"login":"JonnyWong16","id":9099342,"avatar_url":"https://avatars.githubusercontent.com/u/9099342?v=3","gravatar_id":"","url":"https://api.github.com/users/JonnyWong16","html_url":"https://github.com/JonnyWong16","followers_url":"https://api.github.com/users/JonnyWong16/followers","following_url":"https://api.github.com/users/JonnyWong16/following{/other_user}","gists_url":"https://api.github.com/users/JonnyWong16/gists{/gist_id}","starred_url":"https://api.github.com/users/JonnyWong16/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JonnyWong16/subscriptions","organizations_url":"https://api.github.com/users/JonnyWong16/orgs","repos_url":"https://api.github.com/users/JonnyWong16/repos","events_url":"https://api.github.com/users/JonnyWong16/events{/privacy}","received_events_url":"https://api.github.com/users/JonnyWong16/received_events","type":"User","site_admin":false},"body":"'http_hash_password' is to tell if I need to hash a new password.\r\n'http_hashed_password' is to tell if the password in the config file is already hashed.","created_at":"2016-04-24T18:55:02Z","updated_at":"2016-04-24T18:55:02Z","html_url":"https://github.com/drzoidberg33/plexpy/pull/677#discussion_r60849661","pull_request_url":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/677","_links":{"self":{"href":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/comments/60849661"},"html":{"href":"https://github.com/drzoidberg33/plexpy/pull/677#discussion_r60849661"},"pull_request":{"href":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/677"}}},"pull_request":{"url":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/677","id":67133297,"html_url":"https://github.com/drzoidberg33/plexpy/pull/677","diff_url":"https://github.com/drzoidberg33/plexpy/pull/677.diff","patch_url":"https://github.com/drzoidberg33/plexpy/pull/677.patch","issue_url":"https://api.github.com/repos/drzoidberg33/plexpy/issues/677","number":677,"state":"open","locked":false,"title":"Initial implementation of login control","user":{"login":"JonnyWong16","id":9099342,"avatar_url":"https://avatars.githubusercontent.com/u/9099342?v=3","gravatar_id":"","url":"https://api.github.com/users/JonnyWong16","html_url":"https://github.com/JonnyWong16","followers_url":"https://api.github.com/users/JonnyWong16/followers","following_url":"https://api.github.com/users/JonnyWong16/following{/other_user}","gists_url":"https://api.github.com/users/JonnyWong16/gists{/gist_id}","starred_url":"https://api.github.com/users/JonnyWong16/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JonnyWong16/subscriptions","organizations_url":"https://api.github.com/users/JonnyWong16/orgs","repos_url":"https://api.github.com/users/JonnyWong16/repos","events_url":"https://api.github.com/users/JonnyWong16/events{/privacy}","received_events_url":"https://api.github.com/users/JonnyWong16/received_events","type":"User","site_admin":false},"body":"#54 and [FeatHub#1](http://feathub.com/drzoidberg33/plexpy/+1)\r\n\r\nI finally got it working!\r\n\r\n* Adds an HTML login page\r\n* No longer uses cherrypy basic auth\r\n* Uses the admin account set in Settings > Access Control\r\n* Currently only the main pages (tabs) are protected\r\n* Redirect to login page when trying to access a protected page\r\n  * ~~Redirect back to `from_page` after successful login~~ Loads homepage after successful login\r\n\r\n@drzoidberg33 @Hellowlol \r\nI _really_ want you guys to make sure that there are no holes in this before I merge.\r\n\r\nTodo list:\r\n- [x] Fix login redirects when using a base url (`http_root`)\r\n- [x] Hash password in config file (~~use [passlib](https://pythonhosted.org/passlib/lib/passlib.hash.pbkdf2_digest.html#passlib.hash.pbkdf2_sha256) library~~)\r\n- [x] Protect the remaining URIs (not sure how to handle the api decorator with authentication -  protected when accessing directly `/endpoint`, but open with using `/api/v2?cmd=endpoint` with valid api token)\r\n- [x] Add logout button (endpoint `/auth/logout`)\r\n- [x] Make \"Remember me\" checkbox actually do something (sets session for 30 days)\r\n- [x] Login error message when failed attempt\r\n- [ ] Admin login popout from menu or modal\r\n- [ ] Setup user groups for guest access (probably a separate PR)\r\n  - [x] Update `users` table to include `allow_guest`, `user_token`, `server_token`, ~~`session_id`, and `last_login`~~ (sessions handled by CherryPy)\r\n  - [x] Retrieve a Plex token for each user (need to figure out how to do this like [PlexRequests](https://github.com/lokenx/plexrequests-python/issues/2))\r\n    - [x] Retrieve a user access token\r\n    - [x] Retrieve a server access token\r\n    - [x] Save user and server access tokens to database\r\n  - [x] Add global toggle for guest access in Settings > Access Control\r\n  - [ ] Update SQL queries to filter based on logged in user (or just list comprehension after the query? Which is faster?)\r\n  - [ ] Update Plex API calls to use the guest `user_token` instead of the admin's `pms_token` (not really necessary?)\r\n  - [x] Toggle to allow access per user (Users > Edit mode)\r\n  - [ ] Go through all the templates to hide admin stuff\r\n    - [ ] Home (should we show all current activity/stats with masked user info?)\r\n    - [x] Libraries + Individual library page + Info page (only show shared libraries)\r\n    - [x] Users + Individual user page\r\n    - [x] History\r\n    - [x] Graphs\r\n    - [x] Synced Items\r\n    - [x] Settings (disabled for guests)\r\n","created_at":"2016-04-20T06:12:18Z","updated_at":"2016-04-24T18:55:02Z","closed_at":null,"merged_at":null,"merge_commit_sha":"baec11fe1a70e52ca1e6837d9ba06c7b82af332c","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/677/commits","review_comments_url":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/677/comments","review_comment_url":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/comments{/number}","comments_url":"https://api.github.com/repos/drzoidberg33/plexpy/issues/677/comments","statuses_url":"https://api.github.com/repos/drzoidberg33/plexpy/statuses/a0d9726683df6574a733bffb54e482c3ebfcdc08","head":{"label":"JonnyWong16:login-page","ref":"login-page","sha":"a0d9726683df6574a733bffb54e482c3ebfcdc08","user":{"login":"JonnyWong16","id":9099342,"avatar_url":"https://avatars.githubusercontent.com/u/9099342?v=3","gravatar_id":"","url":"https://api.github.com/users/JonnyWong16","html_url":"https://github.com/JonnyWong16","followers_url":"https://api.github.com/users/JonnyWong16/followers","following_url":"https://api.github.com/users/JonnyWong16/following{/other_user}","gists_url":"https://api.github.com/users/JonnyWong16/gists{/gist_id}","starred_url":"https://api.github.com/users/JonnyWong16/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JonnyWong16/subscriptions","organizations_url":"https://api.github.com/users/JonnyWong16/orgs","repos_url":"https://api.github.com/users/JonnyWong16/repos","events_url":"https://api.github.com/users/JonnyWong16/events{/privacy}","received_events_url":"https://api.github.com/users/JonnyWong16/received_events","type":"User","site_admin":false},"repo":{"id":40862882,"name":"plexpy","full_name":"JonnyWong16/plexpy","owner":{"login":"JonnyWong16","id":9099342,"avatar_url":"https://avatars.githubusercontent.com/u/9099342?v=3","gravatar_id":"","url":"https://api.github.com/users/JonnyWong16","html_url":"https://github.com/JonnyWong16","followers_url":"https://api.github.com/users/JonnyWong16/followers","following_url":"https://api.github.com/users/JonnyWong16/following{/other_user}","gists_url":"https://api.github.com/users/JonnyWong16/gists{/gist_id}","starred_url":"https://api.github.com/users/JonnyWong16/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/JonnyWong16/subscriptions","organizations_url":"https://api.github.com/users/JonnyWong16/orgs","repos_url":"https://api.github.com/users/JonnyWong16/repos","events_url":"https://api.github.com/users/JonnyWong16/events{/privacy}","received_events_url":"https://api.github.com/users/JonnyWong16/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/JonnyWong16/plexpy","description":"A Python based monitoring and tracking tool for Plex Media Server.","fork":true,"url":"https://api.github.com/repos/JonnyWong16/plexpy","forks_url":"https://api.github.com/repos/JonnyWong16/plexpy/forks","keys_url":"https://api.github.com/repos/JonnyWong16/plexpy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/JonnyWong16/plexpy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/JonnyWong16/plexpy/teams","hooks_url":"https://api.github.com/repos/JonnyWong16/plexpy/hooks","issue_events_url":"https://api.github.com/repos/JonnyWong16/plexpy/issues/events{/number}","events_url":"https://api.github.com/repos/JonnyWong16/plexpy/events","assignees_url":"https://api.github.com/repos/JonnyWong16/plexpy/assignees{/user}","branches_url":"https://api.github.com/repos/JonnyWong16/plexpy/branches{/branch}","tags_url":"https://api.github.com/repos/JonnyWong16/plexpy/tags","blobs_url":"https://api.github.com/repos/JonnyWong16/plexpy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/JonnyWong16/plexpy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/JonnyWong16/plexpy/git/refs{/sha}","trees_url":"https://api.github.com/repos/JonnyWong16/plexpy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/JonnyWong16/plexpy/statuses/{sha}","languages_url":"https://api.github.com/repos/JonnyWong16/plexpy/languages","stargazers_url":"https://api.github.com/repos/JonnyWong16/plexpy/stargazers","contributors_url":"https://api.github.com/repos/JonnyWong16/plexpy/contributors","subscribers_url":"https://api.github.com/repos/JonnyWong16/plexpy/subscribers","subscription_url":"https://api.github.com/repos/JonnyWong16/plexpy/subscription","commits_url":"https://api.github.com/repos/JonnyWong16/plexpy/commits{/sha}","git_commits_url":"https://api.github.com/repos/JonnyWong16/plexpy/git/commits{/sha}","comments_url":"https://api.github.com/repos/JonnyWong16/plexpy/comments{/number}","issue_comment_url":"https://api.github.com/repos/JonnyWong16/plexpy/issues/comments{/number}","contents_url":"https://api.github.com/repos/JonnyWong16/plexpy/contents/{+path}","compare_url":"https://api.github.com/repos/JonnyWong16/plexpy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/JonnyWong16/plexpy/merges","archive_url":"https://api.github.com/repos/JonnyWong16/plexpy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/JonnyWong16/plexpy/downloads","issues_url":"https://api.github.com/repos/JonnyWong16/plexpy/issues{/number}","pulls_url":"https://api.github.com/repos/JonnyWong16/plexpy/pulls{/number}","milestones_url":"https://api.github.com/repos/JonnyWong16/plexpy/milestones{/number}","notifications_url":"https://api.github.com/repos/JonnyWong16/plexpy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/JonnyWong16/plexpy/labels{/name}","releases_url":"https://api.github.com/repos/JonnyWong16/plexpy/releases{/id}","deployments_url":"https://api.github.com/repos/JonnyWong16/plexpy/deployments","created_at":"2015-08-17T04:15:28Z","updated_at":"2016-02-08T12:00:48Z","pushed_at":"2016-04-24T18:48:37Z","git_url":"git://github.com/JonnyWong16/plexpy.git","ssh_url":"git@github.com:JonnyWong16/plexpy.git","clone_url":"https://github.com/JonnyWong16/plexpy.git","svn_url":"https://github.com/JonnyWong16/plexpy","homepage":"","size":69967,"stargazers_count":1,"watchers_count":1,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":1,"mirror_url":null,"open_issues_count":0,"forks":1,"open_issues":0,"watchers":1,"default_branch":"master"}},"base":{"label":"drzoidberg33:dev","ref":"dev","sha":"9a650b5cd648f72c09873111102275192ebb9c02","user":{"login":"drzoidberg33","id":1313205,"avatar_url":"https://avatars.githubusercontent.com/u/1313205?v=3","gravatar_id":"","url":"https://api.github.com/users/drzoidberg33","html_url":"https://github.com/drzoidberg33","followers_url":"https://api.github.com/users/drzoidberg33/followers","following_url":"https://api.github.com/users/drzoidberg33/following{/other_user}","gists_url":"https://api.github.com/users/drzoidberg33/gists{/gist_id}","starred_url":"https://api.github.com/users/drzoidberg33/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/drzoidberg33/subscriptions","organizations_url":"https://api.github.com/users/drzoidberg33/orgs","repos_url":"https://api.github.com/users/drzoidberg33/repos","events_url":"https://api.github.com/users/drzoidberg33/events{/privacy}","received_events_url":"https://api.github.com/users/drzoidberg33/received_events","type":"User","site_admin":false},"repo":{"id":31169720,"name":"plexpy","full_name":"drzoidberg33/plexpy","owner":{"login":"drzoidberg33","id":1313205,"avatar_url":"https://avatars.githubusercontent.com/u/1313205?v=3","gravatar_id":"","url":"https://api.github.com/users/drzoidberg33","html_url":"https://github.com/drzoidberg33","followers_url":"https://api.github.com/users/drzoidberg33/followers","following_url":"https://api.github.com/users/drzoidberg33/following{/other_user}","gists_url":"https://api.github.com/users/drzoidberg33/gists{/gist_id}","starred_url":"https://api.github.com/users/drzoidberg33/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/drzoidberg33/subscriptions","organizations_url":"https://api.github.com/users/drzoidberg33/orgs","repos_url":"https://api.github.com/users/drzoidberg33/repos","events_url":"https://api.github.com/users/drzoidberg33/events{/privacy}","received_events_url":"https://api.github.com/users/drzoidberg33/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/drzoidberg33/plexpy","description":"A Python based monitoring and tracking tool for Plex Media Server.","fork":false,"url":"https://api.github.com/repos/drzoidberg33/plexpy","forks_url":"https://api.github.com/repos/drzoidberg33/plexpy/forks","keys_url":"https://api.github.com/repos/drzoidberg33/plexpy/keys{/key_id}","collaborators_url":"https://api.github.com/repos/drzoidberg33/plexpy/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/drzoidberg33/plexpy/teams","hooks_url":"https://api.github.com/repos/drzoidberg33/plexpy/hooks","issue_events_url":"https://api.github.com/repos/drzoidberg33/plexpy/issues/events{/number}","events_url":"https://api.github.com/repos/drzoidberg33/plexpy/events","assignees_url":"https://api.github.com/repos/drzoidberg33/plexpy/assignees{/user}","branches_url":"https://api.github.com/repos/drzoidberg33/plexpy/branches{/branch}","tags_url":"https://api.github.com/repos/drzoidberg33/plexpy/tags","blobs_url":"https://api.github.com/repos/drzoidberg33/plexpy/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/drzoidberg33/plexpy/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/drzoidberg33/plexpy/git/refs{/sha}","trees_url":"https://api.github.com/repos/drzoidberg33/plexpy/git/trees{/sha}","statuses_url":"https://api.github.com/repos/drzoidberg33/plexpy/statuses/{sha}","languages_url":"https://api.github.com/repos/drzoidberg33/plexpy/languages","stargazers_url":"https://api.github.com/repos/drzoidberg33/plexpy/stargazers","contributors_url":"https://api.github.com/repos/drzoidberg33/plexpy/contributors","subscribers_url":"https://api.github.com/repos/drzoidberg33/plexpy/subscribers","subscription_url":"https://api.github.com/repos/drzoidberg33/plexpy/subscription","commits_url":"https://api.github.com/repos/drzoidberg33/plexpy/commits{/sha}","git_commits_url":"https://api.github.com/repos/drzoidberg33/plexpy/git/commits{/sha}","comments_url":"https://api.github.com/repos/drzoidberg33/plexpy/comments{/number}","issue_comment_url":"https://api.github.com/repos/drzoidberg33/plexpy/issues/comments{/number}","contents_url":"https://api.github.com/repos/drzoidberg33/plexpy/contents/{+path}","compare_url":"https://api.github.com/repos/drzoidberg33/plexpy/compare/{base}...{head}","merges_url":"https://api.github.com/repos/drzoidberg33/plexpy/merges","archive_url":"https://api.github.com/repos/drzoidberg33/plexpy/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/drzoidberg33/plexpy/downloads","issues_url":"https://api.github.com/repos/drzoidberg33/plexpy/issues{/number}","pulls_url":"https://api.github.com/repos/drzoidberg33/plexpy/pulls{/number}","milestones_url":"https://api.github.com/repos/drzoidberg33/plexpy/milestones{/number}","notifications_url":"https://api.github.com/repos/drzoidberg33/plexpy/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/drzoidberg33/plexpy/labels{/name}","releases_url":"https://api.github.com/repos/drzoidberg33/plexpy/releases{/id}","deployments_url":"https://api.github.com/repos/drzoidberg33/plexpy/deployments","created_at":"2015-02-22T16:36:06Z","updated_at":"2016-04-24T13:35:14Z","pushed_at":"2016-04-24T18:48:38Z","git_url":"git://github.com/drzoidberg33/plexpy.git","ssh_url":"git@github.com:drzoidberg33/plexpy.git","clone_url":"https://github.com/drzoidberg33/plexpy.git","svn_url":"https://github.com/drzoidberg33/plexpy","homepage":"","size":99636,"stargazers_count":562,"watchers_count":562,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":103,"mirror_url":null,"open_issues_count":92,"forks":103,"open_issues":92,"watchers":562,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/677"},"html":{"href":"https://github.com/drzoidberg33/plexpy/pull/677"},"issue":{"href":"https://api.github.com/repos/drzoidberg33/plexpy/issues/677"},"comments":{"href":"https://api.github.com/repos/drzoidberg33/plexpy/issues/677/comments"},"review_comments":{"href":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/677/comments"},"review_comment":{"href":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/drzoidberg33/plexpy/pulls/677/commits"},"statuses":{"href":"https://api.github.com/repos/drzoidberg33/plexpy/statuses/a0d9726683df6574a733bffb54e482c3ebfcdc08"}}}}