Skip to content

Commit

Permalink
Develop/dogwood/201712 (openedx#2369)
Browse files Browse the repository at this point in the history
* Correctly format date block dates.

(cherry picked from commit 22cb307)

* ECOM-3673 Update the course end date description text to remove the reference to certificate when course enrollment is in audit mode

(cherry picked from commit 649e8b1)

* Fixes for courseware date formatting/translation.

(cherry picked from commit 80bfa36)

 Conflicts:
	lms/djangoapps/courseware/date_summary.py

* Fix date summaries with Unicode format issues.

This issue would show up when date formatting strings are translated
with Unicode characters (like when testing with fake Esperanto
translations).

(cherry picked from commit c1a59cc)

* Converts the dates on the dashboard, sidebar navigation, and important course dates to user specified time zone.

(cherry picked from commit 0bf8fc4)

 Conflicts:
	common/djangoapps/util/date_utils.py
	common/lib/xmodule/xmodule/course_module.py
	common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py
	lms/djangoapps/ccx/tests/test_models.py
	lms/djangoapps/courseware/views/index.py
	lms/djangoapps/student_account/views.py
	lms/templates/dashboard/_dashboard_course_listing.html
	openedx/core/djangoapps/content/course_overviews/models.py
	openedx/core/djangoapps/user_api/preferences/api.py
	openedx/core/djangoapps/user_api/preferences/tests/test_views.py

* Display JST for survey's answer datetime. openedx#2146

* Display JST for section's deadline and course start/end datetime. openedx#2146

* Display JST for face-to-face start/end datetime on Django Admin. openedx#2146

* Display JST for ORA2 settings. openedx#2146

* Add the validation of the schedule dates before 1900 openedx#2284 (openedx#2298)

* Implements command count_initial_registration_course openedx#2221 (openedx#2296)

* Add GaCourseEditorRole and GaLmsCourseStaffRole openedx#2150 (openedx#2306)

* Add GaCourseEditorRole and GaLmsCourseStaffRole openedx#2150

* Add UT for studio openedx#2150

* Fix GaCourseEditor has access to after the course closed openedx#2150

* GaLmsCourseStaff can use the same function as the course staff at the staff debug info openedx#2150

* Fix UT and Bok choy openedx#2150

* Remove extra line feed openedx#2150

* Fix comment openedx#2150

* Mod conditions openedx#2150

* Move judgment conditions to template openedx#2150

* Fix comment openedx#2150

* Remove unused code openedx#2150

* Mod conditions for GaCourseEditor but a global staff openedx#2150

* Revert parameter CourseDetails.update_from_json openedx#2150

* Mod check for staff acccess at LMS for GaCourseEditor openedx#2150

* Rename GaCourseEditorRole -> GaGlobalCourseCreatorRole openedx#2150

* Rename GA_COURSE_EDITOR_USER_INFO -> GA_GLOBAL_COURSE_CREATOR_USER_INFO openedx#2150

* Rename GA_ACCESS_CHECK_TYPE_COURSE_EDITOR -> GA_ACCESS_CHECK_TYPE_GLOBAL_COURSE_CREATOR openedx#2150

* Rename Ga_Course_Editor -> Ga_Global_Course_Creator openedx#2150

* Rename gacourseeditor -> gaglobalcoursecreator openedx#2150

* Rename GaCourseEditor -> GaGlobalCourseCreator openedx#2150

* Rename course_editor -> global_course_creator openedx#2150

* Mod hide staff debug info for GaGlobalCourseCreatorRole openedx#2150

* Fix UT for GaGlobalCourseCreator openedx#2150

* Rename UT openedx#2150

* Fix skipped UT openedx#2150

* Remove unused code openedx#2150

* Fix argument openedx#2150

* Remove unused code openedx#2150

* Fix ambiguous conditions openedx#2150

* Rename GaLmsCourseStaffRole -> GaCourseScorerRole openedx#2150

* Rename GA_LMS_COURSE_STAFF_USER_INFO -> GA_COURSE_SCORER_USER_INFO openedx#2150

* Ga_Lms_Course_Staff -> Ga_Course_Scorer openedx#2150

* Rename galmscoursestaff -> gacoursescorer openedx#2150

* Rename GaLmsCourseStaff -> GaCourseScorer openedx#2150

* Rename lms_course_staff -> course_scorer openedx#2150

* Fix translation openedx#2150

* Fix comment openedx#2150

*  Add personal info mask at resign openedx#2148 (openedx#2316)

* Add personal info mask at unenroll openedx#2148

* Fix Review.

* Add Unit Test.

* Add JST date fields near UTC date fields. openedx#2230 (openedx#2307)

* Add JST date fields near UTC date fields. openedx#2230

* Fix Review

* Fix Review 2.

* Add yml Files

* Add option of progress restriction that makes users need to pass prob… (openedx#2305)

* Add option of progress restriction that makes users need to pass problems. openedx#2147

* Skip Bok-Choy CoursewareProgressRestrictionTest temporarily
because this may cause an error of other test

* Fix review 1 openedx#2147

* Fix review 2 openedx#2147

* Fix to use different username and email from test_ga_register.py
so that no error occurs on test_register_and_activate. openedx#2147

* Fix review 3 openedx#2147

* Fix review 4 openedx#2147

* Fix review 5-1

* Fix review 5-2

* Fix review 5-3

* Fix review 5-4

* Fix review 5-5

* Fix review 5-6

* Fix review 5-7

* Fix review 5-8

* Fix review 5-9

* Fix review 5-10

* Fix review 5-12

* Fix review 5-14
revert 5-13

* Fix review 5-15

* Fix review 5-16

* Fix review 6-1 openedx#2147

* Fix review 6-2 openedx#2147

* Fix review 6-3 openedx#2147

* Fix UTC message in survey page. openedx#2340 (openedx#2345)

* Fix bug for manage_user_standing page. openedx#2347 (openedx#2348)

* Fix bug and add failed testcase for mask_resigned_user command. openedx#2362 (openedx#2365)

* Add confirm for account_disabled of manage_user_standing openedx#2366 (openedx#2367)
  • Loading branch information
sakamaki-y authored and SayakaKa committed Dec 21, 2017
1 parent f31e615 commit dd35568
Show file tree
Hide file tree
Showing 142 changed files with 6,455 additions and 336 deletions.
16 changes: 1 addition & 15 deletions biz/djangoapps/ga_contract_operation/personalinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,6 @@ def check_enrollment(self, user):

return True

def disable_user_info(self, user):
"""
Override masked value to user information.
Note: We can `NEVER` restore the masked value.
"""
# To force opt-out state since global course is to be registered on a daily batch.
mask_utils.optout_receiving_global_course_emails(user, self.global_course_ids)
mask_utils.disconnect_third_party_auth(user)
mask_utils.mask_name(user)
mask_utils.mask_email(user)
mask_utils.mask_login_code(user)
mask_utils.delete_certificates(user)

def disable_additional_info(self, contract_register):
"""
Override masked value to additional information.
Expand Down Expand Up @@ -202,7 +188,7 @@ def perform_delegate_personalinfo_mask(entry_id, task_input, action_name):
if not executor.check_enrollment(user):
task_progress.skip()
continue
executor.disable_user_info(user)
mask_utils.disable_user_info(user)
target.complete()
except:
# If an exception occur, logging it and to continue processing next target.
Expand Down
6 changes: 4 additions & 2 deletions biz/djangoapps/ga_invitation/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
from biz.djangoapps.ga_contract.models import Contract, ContractDetail
from biz.djangoapps.ga_invitation.models import ContractRegister
from biz.djangoapps.util.access_utils import has_staff_access
from courseware.access import has_access, GA_ACCESS_CHECK_TYPE_OLD_COURSE_VIEW
from student.roles import CourseBetaTesterRole
from courseware.access import has_access, GA_ACCESS_CHECK_TYPE_GLOBAL_COURSE_CREATOR, GA_ACCESS_CHECK_TYPE_OLD_COURSE_VIEW
from student.roles import CourseBetaTesterRole, GaCourseScorerRole


SpocStatus = namedtuple('SpocStatus', 'is_spoc_course has_spoc_access')
Expand Down Expand Up @@ -42,6 +42,8 @@ def _has_spoc_access(user, contract_ids):
has_staff_access(user, course_id) or
_has_spoc_access(user, _spoc_contract_ids) or
has_access(user, GA_ACCESS_CHECK_TYPE_OLD_COURSE_VIEW, 'global') or
has_access(user, GA_ACCESS_CHECK_TYPE_GLOBAL_COURSE_CREATOR, 'global') or
GaCourseScorerRole(course_id).has_user(user) or
(
Contract.objects.enabled().filter(pk__in=_spoc_contract_ids).exists() and
CourseBetaTesterRole(course_id).has_user(user)
Expand Down
4 changes: 4 additions & 0 deletions biz/djangoapps/ga_invitation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ def get_value_by_display_name(cls, user, contract, display_name):
def find_by_user_and_contract(cls, user, contract):
return cls.objects.filter(user=user, contract=contract)

@classmethod
def find_by_user(cls, user):
return cls.objects.filter(user=user)

@classmethod
def find_by_contract(cls, contract):
return cls.objects.filter(contract=contract).order_by('id')
Expand Down
87 changes: 83 additions & 4 deletions biz/djangoapps/ga_invitation/tests/test_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from courseware.access_utils import ACCESS_DENIED, ACCESS_GRANTED
from courseware.tests.helpers import LoginEnrollmentTestCase
from opaque_keys.edx.keys import CourseKey
from student.roles import CourseBetaTesterRole, CourseStaffRole, GaOldCourseViewerStaffRole, GlobalStaff
from student.roles import CourseBetaTesterRole, CourseStaffRole, GaCourseScorerRole, GaGlobalCourseCreatorRole, GaOldCourseViewerStaffRole, GlobalStaff
from student.tests.factories import UserFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
Expand Down Expand Up @@ -206,7 +206,13 @@ def test_process_request_spoc_course_with_betatester(self):
# has_spoc_access is True if user is not enroll betatesters
self.assertEqual((True, True), self.request.spoc_status)

@ddt.data((GlobalStaff, ACCESS_GRANTED), (GaOldCourseViewerStaffRole, ACCESS_GRANTED), (CourseBetaTesterRole, False))
@ddt.data(
(GlobalStaff, ACCESS_GRANTED),
(GaOldCourseViewerStaffRole, ACCESS_GRANTED),
(GaGlobalCourseCreatorRole, ACCESS_GRANTED),
(GaCourseScorerRole, True),
(CourseBetaTesterRole, False),
)
@ddt.unpack
def test_process_request_spoc_disabled_and_specificate_role(self, data_role, expected_has_access):
course_id = CourseKey.from_string('course-v1:org+course+run')
Expand All @@ -220,7 +226,7 @@ def test_process_request_spoc_disabled_and_specificate_role(self, data_role, exp
)

# Add Role
if data_role is CourseBetaTesterRole:
if data_role is CourseBetaTesterRole or data_role is GaCourseScorerRole:
data_role(course_id).add_users(self.user)
else:
data_role().add_users(self.user)
Expand All @@ -233,7 +239,7 @@ def test_process_request_spoc_disabled_and_specificate_role(self, data_role, exp
SpocStatusMiddleware().process_request(self.request)

# If contract is disabled, has_access is False regardless of the status of ContractRegister
# But global staff and ga_old_course_viewer is True
# But global staff, ga_old_course_viewer and ga_global_course_creator is True
self.assertEqual((True, expected_has_access), self.request.spoc_status)

@ddt.data(
Expand Down Expand Up @@ -439,6 +445,43 @@ def test_spoc_course_with_course_staff(self):
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)

def test_spoc_course_with_ga_global_course_creator(self):
self.setup_user()

# Make user to ga_global_course_creator
GaGlobalCourseCreatorRole().add_users(User.objects.get(pk=self.user.id))

# Create Contract but not SPOC
contract_detail = self._create_contract(
user=self.user,
course_id=self.course.id,
contract_type=CONTRACT_TYPE_PF[0]
)
# Not Create ContractRegister

url = reverse('about_course', args=[self.course.id.to_deprecated_string()])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)

def test_spoc_course_with_ga_course_scorer(self):
self.setup_user()

# Make user to ga_course_scorer
GaCourseScorerRole(self.course.id).add_users(User.objects.get(pk=self.user.id))

# Create Contract but not SPOC
contract_detail = self._create_contract(
user=self.user,
course_id=self.course.id,
contract_type=CONTRACT_TYPE_PF[0]
)
# Not Create ContractRegister

url = reverse('about_course', args=[self.course.id.to_deprecated_string()])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)



@ddt.ddt
class CourseInfoTest(SpocStatusTestBase):
Expand Down Expand Up @@ -619,3 +662,39 @@ def test_spoc_course_with_course_staff(self):
url = reverse('info', args=[self.course.id.to_deprecated_string()])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)

def test_spoc_course_with_ga_global_course_creator(self):
self.setup_user()

# Make user to ga_global_course_creator
GaGlobalCourseCreatorRole().add_users(User.objects.get(pk=self.user.id))

# Create Contract but not SPOC
contract_detail = self._create_contract(
user=self.user,
course_id=self.course.id,
contract_type=CONTRACT_TYPE_PF[0]
)
# Not Create ContractRegister

url = reverse('info', args=[self.course.id.to_deprecated_string()])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)

def test_spoc_course_with_ga_course_scorer(self):
self.setup_user()

# Make user to ga_course_scorer
GaCourseScorerRole(self.course.id).add_users(User.objects.get(pk=self.user.id))

# Create Contract but not SPOC
contract_detail = self._create_contract(
user=self.user,
course_id=self.course.id,
contract_type=CONTRACT_TYPE_PF[0]
)
# Not Create ContractRegister

url = reverse('info', args=[self.course.id.to_deprecated_string()])
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
"""
Management command to mask users who already resigned.
"""

import logging
from optparse import make_option

from django.conf import settings
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand
from django.db import transaction

from biz.djangoapps.util import mask_utils, datetime_utils
from openedx.core.djangoapps.course_global.models import CourseGlobalSetting
from student.models import Registration, UserStanding

log = logging.getLogger(__name__)


class Command(BaseCommand):
"""
Mask users who already resigned.
"""
help = """
Usage: python manage.py lms --settings=aws mask_resigned_user [--debug]
"""

option_list = BaseCommand.option_list + (
make_option('--debug',
default=False,
action='store_true',
help='Use debug log'),
)

def handle(self, *args, **options):
debug = options.get('debug')
if debug:
stream = logging.StreamHandler(self.stdout)
log.addHandler(stream)
log.setLevel(logging.DEBUG)
log.info(u"Command mask_resigned_user started at {}.".format(datetime_utils.timezone_now()))

mask_users = User.objects.filter(
email__contains='@', # Do not mask users who have already masked by biz (#1908)
standing__account_status=UserStanding.ACCOUNT_DISABLED
).order_by('username')

# debug output for comparison with sql output
if debug:
log.debug(u"--------------debug target output (start)--------------")
log.debug('userid,username,email')
for user in mask_users:
log.debug(','.join([str(user.id), user.username, user.email]))
log.debug(u"--------------debug target output (finished)--------------")
else:
failed_users = []

for user in mask_users:
log.info(u"Masked start user_id, user_name : {}, {}.".format(user.id, user.username))
try:
with transaction.atomic():
mask_utils.disable_all_additional_info(user)
mask_utils.disable_user_info(user)
Registration.objects.get(user=user).update_masked()
except:
log.exception(u"Masked failed user_id, user_name : {}, {}.".format(user.id, user.username))
failed_users.append(str(user.id) + '-' + user.username)
else:
log.info(u"Masked success user_id, user_name : {}, {}.".format(user.id, user.username))

if failed_users:
log.error(u"Masked failed users : {}".format(failed_users))

log.info(u"Command mask_user finished at {}.".format(datetime_utils.timezone_now()))
Loading

0 comments on commit dd35568

Please sign in to comment.