diff --git a/Dockerfile b/Dockerfile index 189b0e998b9..d5dce5b303a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -52,6 +52,10 @@ RUN set -ex \ libffi-dev WORKDIR /code + +# Policies +ADD https://github.com/CenterForOpenScience/cos.io.git#master ./COS_POLICIES/ + COPY pyproject.toml . COPY poetry.lock . # Fix: https://github.com/CenterForOpenScience/osf.io/pull/6783 diff --git a/osf/management/commands/email_all_users.py b/osf/management/commands/email_all_users.py index 334ad58933b..f5cbd677fb7 100644 --- a/osf/management/commands/email_all_users.py +++ b/osf/management/commands/email_all_users.py @@ -19,13 +19,13 @@ OFFSET = 500000 -def email_all_users(email_template, dry_run=False, ids=None, run=0, offset=OFFSET): +def email_all_users(email_template, dry_run=False, ids=None, start_id=0, offset=OFFSET): if ids: active_users = OSFUser.objects.filter(id__in=ids) else: - lower_bound = run * offset - upper_bound = (run + 1) * offset + lower_bound = start_id + upper_bound = start_id + offset base_query = OSFUser.objects.filter(date_confirmed__isnull=False, deleted=None).exclude(date_disabled__isnull=False).exclude(is_active=False) active_users = base_query.filter(id__gt=lower_bound, id__lte=upper_bound).order_by('id') @@ -42,11 +42,12 @@ def email_all_users(email_template, dry_run=False, ids=None, run=0, offset=OFFSE total_sent = 0 for user in active_users.iterator(): + logger.info(f'Sending email to {user.id}') try: mails.send_mail( to_addr=user.email, mail=template, - fullname=user.fullname, + given_name=user.given_name or user.fullname, ) except Exception as e: logger.error(f'Exception encountered sending email to {user.id}') @@ -80,11 +81,11 @@ def add_arguments(self, parser): ) parser.add_argument( - '--r', + '--start-id', type=int, - dest='run', + dest='start_id', default=0, - help='Specify which run this is' + help='Specify id to start from.' ) parser.add_argument( @@ -105,9 +106,9 @@ def add_arguments(self, parser): def handle(self, *args, **options): dry_run = options.get('dry_run', False) template = options.get('template') - run = options.get('run') + start_id = options.get('start_id') ids = options.get('ids') offset = options.get('offset', OFFSET) - email_all_users(template, dry_run, run=run, ids=ids, offset=offset) + email_all_users(template, dry_run, start_id=start_id, ids=ids, offset=offset) if dry_run: raise RuntimeError('Dry run, only superusers emailed') diff --git a/osf_tests/management_commands/test_email_all_users.py b/osf_tests/management_commands/test_email_all_users.py index 3392e77a470..c10c84b49d1 100644 --- a/osf_tests/management_commands/test_email_all_users.py +++ b/osf_tests/management_commands/test_email_all_users.py @@ -49,7 +49,7 @@ def test_email_all_users_dry(self, mock_email, superuser): mock_email.assert_called_with( to_addr=superuser.email, mail=mails.TOU_NOTIF, - fullname=superuser.fullname + given_name=superuser.given_name ) @pytest.mark.django_db @@ -64,10 +64,10 @@ def test_dont_email_inactive_users( @pytest.mark.django_db @mock.patch('website.mails.send_mail') def test_email_all_users_offset(self, mock_email, user, user2): - email_all_users('TOU_NOTIF', offset=1, run=0) + email_all_users('TOU_NOTIF', offset=1, start_id=0) - email_all_users('TOU_NOTIF', offset=1, run=1) + email_all_users('TOU_NOTIF', offset=1, start_id=1) - email_all_users('TOU_NOTIF', offset=1, run=2) + email_all_users('TOU_NOTIF', offset=1, start_id=2) assert mock_email.call_count == 2 diff --git a/website/policies/views.py b/website/policies/views.py new file mode 100644 index 00000000000..c13ad197dae --- /dev/null +++ b/website/policies/views.py @@ -0,0 +1,19 @@ +import markdown + +from website.settings import \ + PRIVACY_POLICY_PATH, PRIVACY_POLICY_GITHUB_LINK, \ + TERMS_POLICY_PATH, TERMS_POLICY_GITHUB_LINK + +def privacy_policy(): + with open(PRIVACY_POLICY_PATH, 'r') as policy_file: + return { + 'policy_content': markdown.markdown(policy_file.read(), extensions=['toc']), + 'POLICY_GITHUB_LINK': PRIVACY_POLICY_GITHUB_LINK + } + +def terms_policy(): + with open(TERMS_POLICY_PATH, 'r') as policy_file: + return { + 'policy_content': markdown.markdown(policy_file.read(), extensions=['toc']), + 'POLICY_GITHUB_LINK': TERMS_POLICY_GITHUB_LINK + } diff --git a/website/routes.py b/website/routes.py index 2acd71db1a6..ce328c3dcd7 100644 --- a/website/routes.py +++ b/website/routes.py @@ -53,6 +53,7 @@ from addons.base import views as addon_views from website.discovery import views as discovery_views from website.conferences import views as conference_views +from website.policies import views as policy_views from website.preprints import views as preprint_views from website.registries import views as registries_views from website.reviews import views as reviews_views @@ -1145,6 +1146,18 @@ def make_url_map(app): Rule('/goodbye/', 'get', goodbye, notemplate), + Rule( + '/privacy_policy/', + 'get', + policy_views.privacy_policy, + OsfWebRenderer('policies/generic_policy.mako', trust=True) + ), + Rule( + '/terms_of_use/', + 'get', + policy_views.terms_policy, + OsfWebRenderer('policies/generic_policy.mako', trust=True) + ), Rule( [ '/project//', diff --git a/website/settings/defaults.py b/website/settings/defaults.py index 91e3c1bacc6..ee667f4130e 100644 --- a/website/settings/defaults.py +++ b/website/settings/defaults.py @@ -26,6 +26,9 @@ def parent_dir(path): STATIC_FOLDER = os.path.join(BASE_PATH, 'static') STATIC_URL_PATH = '/static' ASSET_HASH_PATH = os.path.join(APP_PATH, 'webpack-assets.json') +POLICY_PATH = os.path.join(APP_PATH, 'COS_POLICIES') +PRIVACY_POLICY_PATH = os.path.join(POLICY_PATH, 'PRIVACY_POLICY.md') +TERMS_POLICY_PATH = os.path.join(POLICY_PATH, 'TERMS_OF_USE.md') ROOT = os.path.join(BASE_PATH, '..') BCRYPT_LOG_ROUNDS = 12 LOG_LEVEL = logging.INFO @@ -2048,10 +2051,12 @@ class CeleryConfig: OSF_REGISTRIES_LOGO = 'osf_registries' OSF_LOGO_LIST = [OSF_LOGO, OSF_PREPRINTS_LOGO, OSF_MEETINGS_LOGO, OSF_PREREG_LOGO, OSF_REGISTRIES_LOGO] +PRIVACY_POLICY_GITHUB_LINK = 'https://github.com/CenterForOpenScience/centerforopenscience.org/blob/master/PRIVACY_POLICY.md' +TERMS_POLICY_GITHUB_LINK = 'https://github.com/CenterForOpenScience/centerforopenscience.org/blob/master/TERMS_OF_USE.md' FOOTER_LINKS = { - 'terms': 'https://github.com/CenterForOpenScience/centerforopenscience.org/blob/master/TERMS_OF_USE.md', - 'privacyPolicy': 'https://github.com/CenterForOpenScience/centerforopenscience.org/blob/master/PRIVACY_POLICY.md', - 'cookies': 'https://github.com/CenterForOpenScience/centerforopenscience.org/blob/master/PRIVACY_POLICY.md#f-cookies', + 'terms': 'https://osf.io/terms_of_use/', + 'privacyPolicy': 'https://osf.io/privacy_policy/', + 'cookies': 'https://osf.io/privacy_policy/#f-cookies', 'cos': 'https://cos.io', 'statusPage': 'https://status.cos.io/', 'apiDocs': 'https://developer.osf.io/', diff --git a/website/templates/emails/tou_notif.html.mako b/website/templates/emails/tou_notif.html.mako index 1da8c0cbc07..56130626668 100644 --- a/website/templates/emails/tou_notif.html.mako +++ b/website/templates/emails/tou_notif.html.mako @@ -3,12 +3,12 @@ <%def name="content()"> - Hi ${fullname},
+ Hi ${given_name},

- On August 10, 2020 the COS Websites and Services Terms of Use will change. The updates to the Terms are necessary to support continued use of the Websites and Services by the public.
- To better understand what has changed, go here.
+ On Friday, January 10, 2025 the COS Websites and Services Terms of Use and Privacy Policy will change. The updates to the Terms are necessary to support continued use of the Websites and Services by the public.
+ To better understand what has changed, see the Terms of Use change summary and Privacy Policy change summary.

- If you have any questions email support@osf.io.
+ You do not need to take any actions to acknowledge these updates. If you have any questions, please email support@osf.io.

Regards,

diff --git a/website/templates/policies/generic_policy.mako b/website/templates/policies/generic_policy.mako new file mode 100644 index 00000000000..6ae8581d350 --- /dev/null +++ b/website/templates/policies/generic_policy.mako @@ -0,0 +1,16 @@ +<%inherit file="base.mako"/> + +<%def name="content()"> +
+
+
+
+ ${policy_content} +
+
+
+ Version history for this policy is available here +
+
+
+