{"action":"created","comment":{"url":"https://api.github.com/repos/edx/edx-platform/pulls/comments/71727001","id":71727001,"diff_hunk":"@@ -0,0 +1,145 @@\n+\"\"\"\n+Views file for the Darklang Django App\n+\"\"\"\n+from openedx.core.lib.api.view_utils import view_auth_classes\n+from django.views.generic.base import View\n+from django.contrib.auth.decorators import login_required\n+from django.utils.decorators import method_decorator\n+\n+from edxmako.shortcuts import render_to_response\n+\n+from openedx.core.djangoapps.user_api.preferences.api import (\n+    delete_user_preference, get_user_preference, set_user_preference\n+)\n+from lang_pref import LANGUAGE_KEY\n+\n+from django.utils.translation import LANGUAGE_SESSION_KEY\n+from django.utils.translation import ugettext as _\n+\n+from dark_lang import DARK_LANGUAGE_KEY\n+from dark_lang.models import DarkLangConfig\n+\n+LANGUAGE_INPUT_FIELD = 'preview_lang'\n+\n+\n+@view_auth_classes()\n+class DarkLangView(View):\n+    \"\"\"\n+    View used when a user is attempting to change the preview language using Darklang.\n+\n+    Expected Behavior:\n+    GET - returns a form for setting/resetting the user's dark language\n+    POST - updates or clears the setting to the given dark language\n+\n+    Note: This class and View are meant to replace the ability to set the DarkLang in the middleware, which was\n+    determined to be a security risk. (TNL-4742)\n+    \"\"\"\n+    template_name = 'darklang/preview_lang.html'\n+\n+    @method_decorator(login_required)\n+    def get(self, request):\n+        \"\"\"\n+        Displays the Form for setting/resetting a User's dark language setting\n+\n+        Arguments:\n+            request (Request): The Django Request Object\n+\n+        Returns:\n+            HttpResponse: View containing the form for setting the preview lang\n+        \"\"\"\n+        context = {\n+            'disable_courseware_js': True,\n+            'uses_pattern_library': True\n+        }\n+        return render_to_response(self.template_name, context)\n+\n+    @method_decorator(login_required)\n+    def post(self, request):\n+        \"\"\"\n+        Sets or clears the DarkLang depending on the incoming post data.\n+\n+        Arguments:\n+            request (Request): The Django Request Object\n+\n+        Returns:\n+            HttpResponse: View containing the form for setting the preview lang\n+        \"\"\"\n+        context = {\n+            'disable_courseware_js': True,\n+            'uses_pattern_library': True\n+        }\n+        result = self.process_darklang_request(request)\n+        if result is not None:\n+            context.update({'form_submit_message': result})\n+        return render_to_response(self.template_name, context)\n+\n+    def process_darklang_request(self, request):\n+        \"\"\"\n+        Prevent user from requesting un-released languages\n+        \"\"\"\n+        if not DarkLangConfig.current().enabled:\n+            return None\n+\n+        if 'reset' in request.POST:\n+            # Reset and clear the language preference\n+            return self._clear_preview_language(request)\n+        if 'set_language' in request.POST:\n+            # Set the Preview Language\n+            return self._set_preview_language(request)\n+\n+    def _set_preview_language(self, request):\n+        \"\"\"\n+        Attempt to set the Preview language\n+\n+        Arguments:\n+            request (Request): The incoming Django Request\n+\n+        Returns:\n+            str: The response message to be presented\n+        \"\"\"\n+        if LANGUAGE_INPUT_FIELD not in request.POST:\n+            return _('Language code not provided')\n+\n+        preview_lang = request.POST[LANGUAGE_INPUT_FIELD]\n+\n+        if preview_lang == '':\n+            return _('Language code not provided')\n+\n+        auth_user = request.user.is_authenticated()\n+\n+        # Set the session key to the requested preview lang\n+        request.session[LANGUAGE_SESSION_KEY] = preview_lang\n+\n+        # Make sure that we set the requested preview lang as the dark lang preference for the\n+        # user, so that the lang_pref middleware doesn't clobber away the dark lang preview.\n+        if auth_user:\n+            set_user_preference(request.user, DARK_LANGUAGE_KEY, preview_lang)\n+        return _('Language set to language code: {}').format(preview_lang)\n+\n+    def _clear_preview_language(self, request):\n+        \"\"\"\n+        Clears the dark language preview\n+\n+        Arguments:\n+            request (Request): The incoming Django Request\n+\n+        Returns:\n+            str: The response message to be presented\n+        \"\"\"\n+        auth_user = request.user.is_authenticated()\n+\n+        # delete the session language key (if one is set)\n+        if LANGUAGE_SESSION_KEY in request.session:\n+            del request.session[LANGUAGE_SESSION_KEY]\n+\n+        user_pref = ''\n+        if auth_user:\n+            # Reset user's dark lang preference to null\n+            delete_user_preference(request.user, DARK_LANGUAGE_KEY)\n+            # Get & set user's preferred language\n+            user_pref = get_user_preference(request.user, LANGUAGE_KEY)\n+            if user_pref:\n+                request.session[LANGUAGE_SESSION_KEY] = user_pref\n+        if user_pref is None:\n+            return _('Language reset user default')","path":"common/djangoapps/dark_lang/views.py","position":144,"original_position":144,"commit_id":"f06994ffa986613128ca48d95d3fbcca6912cc30","original_commit_id":"f06994ffa986613128ca48d95d3fbcca6912cc30","user":{"login":"cahrens","id":484484,"avatar_url":"https://avatars.githubusercontent.com/u/484484?v=3","gravatar_id":"","url":"https://api.github.com/users/cahrens","html_url":"https://github.com/cahrens","followers_url":"https://api.github.com/users/cahrens/followers","following_url":"https://api.github.com/users/cahrens/following{/other_user}","gists_url":"https://api.github.com/users/cahrens/gists{/gist_id}","starred_url":"https://api.github.com/users/cahrens/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cahrens/subscriptions","organizations_url":"https://api.github.com/users/cahrens/orgs","repos_url":"https://api.github.com/users/cahrens/repos","events_url":"https://api.github.com/users/cahrens/events{/privacy}","received_events_url":"https://api.github.com/users/cahrens/received_events","type":"User","site_admin":false},"body":"I find this message confusing. Can you come up with better wording for this case?","created_at":"2016-07-21T15:23:18Z","updated_at":"2016-07-21T15:23:19Z","html_url":"https://github.com/edx/edx-platform/pull/13018#discussion_r71727001","pull_request_url":"https://api.github.com/repos/edx/edx-platform/pulls/13018","_links":{"self":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/comments/71727001"},"html":{"href":"https://github.com/edx/edx-platform/pull/13018#discussion_r71727001"},"pull_request":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/13018"}}},"pull_request":{"url":"https://api.github.com/repos/edx/edx-platform/pulls/13018","id":77824867,"html_url":"https://github.com/edx/edx-platform/pull/13018","diff_url":"https://github.com/edx/edx-platform/pull/13018.diff","patch_url":"https://github.com/edx/edx-platform/pull/13018.patch","issue_url":"https://api.github.com/repos/edx/edx-platform/issues/13018","number":13018,"state":"open","locked":false,"title":"Tnl 4742 dark lang changes","user":{"login":"staubina","id":2854941,"avatar_url":"https://avatars.githubusercontent.com/u/2854941?v=3","gravatar_id":"","url":"https://api.github.com/users/staubina","html_url":"https://github.com/staubina","followers_url":"https://api.github.com/users/staubina/followers","following_url":"https://api.github.com/users/staubina/following{/other_user}","gists_url":"https://api.github.com/users/staubina/gists{/gist_id}","starred_url":"https://api.github.com/users/staubina/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/staubina/subscriptions","organizations_url":"https://api.github.com/users/staubina/orgs","repos_url":"https://api.github.com/users/staubina/repos","events_url":"https://api.github.com/users/staubina/events{/privacy}","received_events_url":"https://api.github.com/users/staubina/received_events","type":"User","site_admin":false},"body":"https://studio-staubina.sandbox.edx.org\r\n\r\n### Description\r\n \r\n[TNL-4742](https://openedx.atlassian.net/browse/TNL-4742)\r\n\r\n- Removed the preview_lang and clear_lang as URL parameters to deal with security concern with CSRF. (More detail in Jira)\r\n- Created a new method and form to set the preview language\r\n- Updated/Refactored tests to reflect this new method\r\n\r\n### Sandbox\r\n- [ ] Build a sandbox for your branch and add a link here\r\n- Links for testing\r\n\t+ https://staubina.sandbox.edx.org/update_lang/\r\n\t+ https://studio-staubina.sandbox.edx.org/update_lang/\r\n\r\n### Testing\r\n- [ ] i18n\r\n- [ ] RTL\r\n- [ ] safecommit shows 0 violations\r\n- [ ] Unit, integration, acceptance tests as appropriate\r\n\r\n#### Instruction for manual test\r\n1. Go to url for LMS or CMS provided above (/update_lang/)\r\n2. Log in\r\n3. Set the language to eo using the provided form\r\n4. Go to a different page within the site and ensure the language setting sticks with the session\r\n5. go to the update_lang site again and reset the language\r\n6. Go to a different page with the site and ensure the language is reset as expected\r\n\r\n### Reviewers\r\nIf you've been tagged for review, please check your corresponding box once you've given the :+1:.\r\n- [ ] Code review: @cahrens \r\n- [ ] Code review: @nasthagiri \r\n- [ ] Doc Review: @catong - What is needed for documentation updates?\r\n- [ ] Community Review: @nedbat - How do we update the community on this change?\r\n\r\n### Post-review\r\n- [ ] Squash commits","created_at":"2016-07-18T15:11:55Z","updated_at":"2016-07-21T15:23:19Z","closed_at":null,"merged_at":null,"merge_commit_sha":"9501fc31f49b8fab258301c307dd6f1dc56f5754","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/edx/edx-platform/pulls/13018/commits","review_comments_url":"https://api.github.com/repos/edx/edx-platform/pulls/13018/comments","review_comment_url":"https://api.github.com/repos/edx/edx-platform/pulls/comments{/number}","comments_url":"https://api.github.com/repos/edx/edx-platform/issues/13018/comments","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/f06994ffa986613128ca48d95d3fbcca6912cc30","head":{"label":"edx:TNL-4742_DarkLangChanges","ref":"TNL-4742_DarkLangChanges","sha":"f06994ffa986613128ca48d95d3fbcca6912cc30","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":10391073,"name":"edx-platform","full_name":"edx/edx-platform","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/edx-platform","description":"The Open edX platform, the software that powers edX!","fork":false,"url":"https://api.github.com/repos/edx/edx-platform","forks_url":"https://api.github.com/repos/edx/edx-platform/forks","keys_url":"https://api.github.com/repos/edx/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/edx-platform/teams","hooks_url":"https://api.github.com/repos/edx/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/edx/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/edx/edx-platform/events","assignees_url":"https://api.github.com/repos/edx/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/edx/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/edx/edx-platform/tags","blobs_url":"https://api.github.com/repos/edx/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/edx-platform/languages","stargazers_url":"https://api.github.com/repos/edx/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/edx/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/edx/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/edx/edx-platform/subscription","commits_url":"https://api.github.com/repos/edx/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/edx/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/edx-platform/merges","archive_url":"https://api.github.com/repos/edx/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/edx-platform/downloads","issues_url":"https://api.github.com/repos/edx/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/edx/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/edx/edx-platform/releases{/id}","deployments_url":"https://api.github.com/repos/edx/edx-platform/deployments","created_at":"2013-05-30T20:20:38Z","updated_at":"2016-07-21T15:12:15Z","pushed_at":"2016-07-21T15:19:12Z","git_url":"git://github.com/edx/edx-platform.git","ssh_url":"git@github.com:edx/edx-platform.git","clone_url":"https://github.com/edx/edx-platform.git","svn_url":"https://github.com/edx/edx-platform","homepage":"http://open.edx.org/","size":795406,"stargazers_count":2678,"watchers_count":2678,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1616,"mirror_url":null,"open_issues_count":195,"forks":1616,"open_issues":195,"watchers":2678,"default_branch":"master"}},"base":{"label":"edx:master","ref":"master","sha":"51bb4d4e003d485f7db199800162f3052f4b2cf7","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":10391073,"name":"edx-platform","full_name":"edx/edx-platform","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars.githubusercontent.com/u/3179841?v=3","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/edx-platform","description":"The Open edX platform, the software that powers edX!","fork":false,"url":"https://api.github.com/repos/edx/edx-platform","forks_url":"https://api.github.com/repos/edx/edx-platform/forks","keys_url":"https://api.github.com/repos/edx/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/edx-platform/teams","hooks_url":"https://api.github.com/repos/edx/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/edx/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/edx/edx-platform/events","assignees_url":"https://api.github.com/repos/edx/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/edx/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/edx/edx-platform/tags","blobs_url":"https://api.github.com/repos/edx/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/edx-platform/languages","stargazers_url":"https://api.github.com/repos/edx/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/edx/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/edx/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/edx/edx-platform/subscription","commits_url":"https://api.github.com/repos/edx/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/edx/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/edx-platform/merges","archive_url":"https://api.github.com/repos/edx/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/edx-platform/downloads","issues_url":"https://api.github.com/repos/edx/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/edx/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/edx/edx-platform/releases{/id}","deployments_url":"https://api.github.com/repos/edx/edx-platform/deployments","created_at":"2013-05-30T20:20:38Z","updated_at":"2016-07-21T15:12:15Z","pushed_at":"2016-07-21T15:19:12Z","git_url":"git://github.com/edx/edx-platform.git","ssh_url":"git@github.com:edx/edx-platform.git","clone_url":"https://github.com/edx/edx-platform.git","svn_url":"https://github.com/edx/edx-platform","homepage":"http://open.edx.org/","size":795406,"stargazers_count":2678,"watchers_count":2678,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1616,"mirror_url":null,"open_issues_count":195,"forks":1616,"open_issues":195,"watchers":2678,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/13018"},"html":{"href":"https://github.com/edx/edx-platform/pull/13018"},"issue":{"href":"https://api.github.com/repos/edx/edx-platform/issues/13018"},"comments":{"href":"https://api.github.com/repos/edx/edx-platform/issues/13018/comments"},"review_comments":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/13018/comments"},"review_comment":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/13018/commits"},"statuses":{"href":"https://api.github.com/repos/edx/edx-platform/statuses/f06994ffa986613128ca48d95d3fbcca6912cc30"}}}}
{"actor":{"display_login":"cahrens"}}