diff --git a/README-docker-compose.md b/README-docker-compose.md index 8e0bc875a8a..47b0653ef2e 100644 --- a/README-docker-compose.md +++ b/README-docker-compose.md @@ -171,7 +171,7 @@ - When starting with an empty database you will need to run migrations and populate preprint providers. See the [Running arbitrary commands](#running-arbitrary-commands) section below for instructions. 6. Start the OSF Web, API Server, and Preprints (Detached) ```bash - docker compose up -d worker web api admin preprints ember_osf_web gv + docker compose up -d worker web api admin preprints gv ``` 7. View the OSF at [http://localhost:5000](http://localhost:5000). @@ -181,7 +181,7 @@ - Once the requirements have all been installed, you can start the OSF in the background with ```bash - docker compose up -d assets admin_assets mfr wb fakecas sharejs worker web api admin preprints ember_osf_web gv + docker compose up -d assets admin_assets mfr wb fakecas sharejs worker web api admin preprints gv ``` - To view the logs for a given container: @@ -270,14 +270,10 @@ ```bash docker compose run --rm web python3 -m scripts.parse_citation_styles ``` -- Start ember_osf_web - - Needed for ember app: - - `docker-compose up -d ember_osf_web` - OPTIONAL: Register OAuth Scopes - - Needed for things such as the ember-osf dummy app - ```bash - docker compose run --rm web python3 -m scripts.register_oauth_scopes - ``` + ```bash + docker compose run --rm web python3 -m scripts.register_oauth_scopes + ``` - OPTIONAL: Create migrations: - After changing a model you will need to create migrations and apply them. Migrations are python code that changes either the structure or the data of a database. This will compare the django models on disk to the database, find the differences, and create migration code to change the database. If there are no changes this command is a noop. ```bash @@ -500,4 +496,4 @@ wb: ### Running Collections -To run collections, you must uncomment COLLECTIONS_ENABLED=true in docker-compose.yml under ember_osf_web, then recreate your ember and web containers. +To run collections, you must uncomment COLLECTIONS_ENABLED=true in docker-compose.yml, then recreate web container. diff --git a/addons/base/views.py b/addons/base/views.py index 93be2d0c26a..230c72c6f61 100644 --- a/addons/base/views.py +++ b/addons/base/views.py @@ -922,12 +922,12 @@ def addon_view_or_download_file(auth, path, provider, **kwargs): ) ) - # There's no download action redirect to the Ember front-end file view and create guid. + # There's no download action redirect to the front-end file view and create guid. if action != 'download': - if isinstance(target, Node) and flag_is_active(request, features.EMBER_FILE_PROJECT_DETAIL): + if isinstance(target, Node): guid = file_node.get_guid(create=True) return redirect(f'{settings.DOMAIN}{guid._id}/') - if isinstance(target, Registration) and flag_is_active(request, features.EMBER_FILE_REGISTRATION_DETAIL): + if isinstance(target, Registration): guid = file_node.get_guid(create=True) return redirect(f'{settings.DOMAIN}{guid._id}/') diff --git a/addons/osfstorage/tests/test_views.py b/addons/osfstorage/tests/test_views.py index 23df3a136fd..16d928e3343 100644 --- a/addons/osfstorage/tests/test_views.py +++ b/addons/osfstorage/tests/test_views.py @@ -36,7 +36,6 @@ from osf_tests.factories import ProjectFactory, ApiOAuth2PersonalTokenFactory, PreprintFactory from website.files.utils import attach_versions -from website.settings import EXTERNAL_EMBER_APPS from api_tests.draft_nodes.views.test_draft_node_files_lists import prepare_mock_wb_response @@ -1413,28 +1412,17 @@ def test_file_view_updates_history(self): {'name': 'testpath', 'path': '/testpath', 'materialized': '/testpath', 'kind': 'file'}, ] ) - with override_flag(features.EMBER_FILE_PROJECT_DETAIL, active=True): - url = self.node.web_url_for('addon_view_or_download_file', path='testpath', provider='github') - self.app.get(url, auth=self.user.auth) - file = GithubFile.objects.get(_path='/testpath', provider='github') - assert file.history - - @mock.patch('website.views.stream_emberapp') - def test_file_views(self, mock_ember): - with override_flag(features.EMBER_FILE_PROJECT_DETAIL, active=True): - file = create_test_file(target=self.node, user=self.user) - url = self.node.web_url_for('addon_view_or_download_file', path=file._id, provider=file.provider) - res = self.app.get(url, auth=self.user.auth) - assert res.status_code == 302 - assert res.headers['Location'] == f'{settings.DOMAIN}{file.get_guid()._id}/' - assert not mock_ember.called - res = self.app.get(url, auth=self.user.auth, follow_redirects=True) - assert res.status_code == 200 - assert mock_ember.called - args, kwargs = mock_ember.call_args - - assert args[0] == EXTERNAL_EMBER_APPS['ember_osf_web']['server'] - assert args[1] == EXTERNAL_EMBER_APPS['ember_osf_web']['path'].rstrip('/') + url = self.node.web_url_for('addon_view_or_download_file', path='testpath', provider='github') + self.app.get(url, auth=self.user.auth) + file = GithubFile.objects.get(_path='/testpath', provider='github') + assert file.history + + def test_file_views(self): + file = create_test_file(target=self.node, user=self.user) + url = self.node.web_url_for('addon_view_or_download_file', path=file._id, provider=file.provider) + res = self.app.get(url, auth=self.user.auth) + assert res.status_code == 302 + assert res.headers['Location'] == f'{settings.DOMAIN}{file.get_guid()._id}/' def test_download_file(self): file = create_test_file(target=self.node, user=self.user) diff --git a/addons/wiki/views.py b/addons/wiki/views.py index 11009c10b07..fed244cd97d 100644 --- a/addons/wiki/views.py +++ b/addons/wiki/views.py @@ -13,11 +13,9 @@ from addons.wiki import settings from addons.wiki import utils as wiki_utils from addons.wiki.models import WikiPage, WikiVersion -from osf import features from website.profile.utils import get_profile_image_url from website.project.views.node import _view_project from website.project.model import has_anonymous_link -from website.ember_osf_web.decorators import ember_flag_is_active from website.project.decorators import ( must_be_contributor_or_public, must_have_addon, must_not_be_registration, @@ -358,7 +356,6 @@ def get_node_wiki_permissions(node, auth, **kwargs): @must_be_valid_project @must_have_addon('wiki', 'node') -@ember_flag_is_active(features.EMBER_PROJECT_WIKI) def project_wiki_home(**kwargs): node = kwargs['node'] or kwargs['project'] return redirect(node.web_url_for('project_wiki_view', wname='home', _guid=True)) diff --git a/api/sparse/serializers.py b/api/sparse/serializers.py index a085b7344ec..97142771296 100644 --- a/api/sparse/serializers.py +++ b/api/sparse/serializers.py @@ -23,7 +23,7 @@ class SparseNodeSerializer(NodeSerializer): 'contributors', ]) links = LinksField({ - 'self': 'get_absolute_url', # self links will break ember data unless we make a specific sparse detail serializer + 'self': 'get_absolute_url', 'html': 'get_absolute_html_url', }) detail = RelationshipField( @@ -109,7 +109,7 @@ class SparseRegistrationSerializer(RegistrationSerializer): ]) links = LinksField({ - 'self': 'get_absolute_url', # self links will break ember data unless we make a specific sparse detail serializer + 'self': 'get_absolute_url', 'html': 'get_absolute_html_url', }) detail = RelationshipField( diff --git a/api_tests/users/views/test_user_confirm_external_login.py b/api_tests/users/views/test_user_confirm_external_login.py index bcac3fb1d6c..7a877017a96 100644 --- a/api_tests/users/views/test_user_confirm_external_login.py +++ b/api_tests/users/views/test_user_confirm_external_login.py @@ -34,7 +34,7 @@ def payload(self, user_one): 'attributes': { 'uid': user_one._id, 'token': user_one.get_confirmation_token(user_one.username), - 'destination': 'dashboard', + 'destination': 'my_projects', } } } diff --git a/docker-compose-dist.override.yml b/docker-compose-dist.override.yml index 7a35d24b27b..3a3c2fb8160 100644 --- a/docker-compose-dist.override.yml +++ b/docker-compose-dist.override.yml @@ -29,80 +29,6 @@ # volumes: # - ../modular-file-renderer:/code:cached -# preprints: -# volumes: -# - ../ember-osf-preprints:/code:cached -# -## # Use this for ember-osf linked development: -## - preprints_dist_vol:/code/dist -## - ../ember-osf:/ember-osf -## depends_on: -## - emberosf -## command: -## - /bin/bash -## - -c -## - cd /ember-osf && -## yarn link && -## cd /code && -## (rm -r node_modules || true) && -## yarn --frozen-lockfile && -## yarn link @centerforopenscience/ember-osf && -## (rm -r bower_components || true) && -## ./node_modules/.bin/bower install --allow-root --config.interactive=false && -## yarn start --host 0.0.0.0 --port 4201 --live-reload-port 41954 - -# registries: -# volumes: -# - ../ember-osf-registries:/code:cached -# -## # Use this for ember-osf linked development: -## - registries_dist_vol:/code/dist -## - ../ember-osf:/ember-osf -## depends_on: -## - emberosf -## command: -## - /bin/bash -## - -c -## - cd /ember-osf && -## yarn link && -## cd /code && -## (rm -r node_modules || true) && -## yarn --frozen-lockfile && -## yarn link @centerforopenscience/ember-osf && -## yarn start --host 0.0.0.0 --port 4202 --live-reload-port 41955 - -# reviews: -# volumes: -# - ../ember-osf-reviews:/code:cached -# -## # Use this for ember-osf linked development: -## - reviews_dist_vol:/code/dist -## - ../ember-osf:/ember-osf -## depends_on: -## - emberosf -## command: -## - /bin/bash -## - -c -## - cd /ember-osf && -## yarn link && -## cd /code && -## yarn link @centerforopenscience/ember-osf && -## yarn --frozen-lockfile && -## yarn start --host 0.0.0.0 --port 4203 --live-reload-port 41956 - -# # Use this for ember-osf linked development: -# emberosf: -# build: ../ember-osf -# command: -# - /bin/bash -# - -c -# - (rm -r node_modules || true) && -# yarn --frozen-lockfile --ignore-engines && -# (rm -r bower_components || true) && -# ./node_modules/.bin/bower install --allow-root --config.interactive=false -# volumes: -# - ../ember-osf/:/code:nocopy - # #################### # # RabbitMQ SSL # # Enable this, place the certs in ./ssl, and uncomment the BROKER_USE_SSL dictionary in local.py diff --git a/docker-compose.yml b/docker-compose.yml index f00b589f7e0..9914c24728b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -15,8 +15,6 @@ volumes: external: false rabbitmq_vol: external: false - ember_osf_web_dist_vol: - external: false preprints_dist_vol: external: false reviews_dist_vol: @@ -255,35 +253,6 @@ services: - postgres stdin_open: true - - ################# - # Ember OSF Web # - ################# - - ember_osf_web: - image: quay.io/centerforopenscience/osf-web:develop-local - command: yarn run start --path dist --host 0.0.0.0 --port 4200 --live-reload-port 41953 - restart: unless-stopped - depends_on: - - api - - web - environment: - # Uncomment below to enable collections on ember - # - COLLECTIONS_ENABLED=true - - BACKEND=local - - SHARE_BASE_URL=http://localhost:8003/ - - SHARE_API_URL=http://localhost:8003/api/v2 - - SHARE_SEARCH_URL=http://localhost:8003/api/v2/search/creativeworks/_search - expose: - - 4200 - - 41953 - ports: - - 4200:4200 - - 41953:41953 - volumes: - - ember_osf_web_dist_vol:/code/dist - stdin_open: true - ############# # Preprints # ############# @@ -523,7 +492,6 @@ services: - osf_requirements_3_12_vol:/usr/local/lib/python3.12/ - osf_bower_components_vol:/code/website/static/vendor/bower_components - osf_node_modules_vol:/code/node_modules - - ember_osf_web_dist_vol:/ember_osf_web - preprints_dist_vol:/preprints - reviews_dist_vol:/reviews stdin_open: true diff --git a/framework/auth/campaigns.py b/framework/auth/campaigns.py index 725ff9cd685..8a76933033d 100644 --- a/framework/auth/campaigns.py +++ b/framework/auth/campaigns.py @@ -94,7 +94,7 @@ def get_campaigns(): newest_campaigns.update({ 'agu_conference_2023': { 'system_tag': CampaignSourceTags.AguConference2023.value, - 'redirect_url': furl(DOMAIN).add(path='dashboard/').url, + 'redirect_url': furl(DOMAIN).add(path='my_projects/').url, 'confirmation_email_template': mails.CONFIRM_EMAIL_AGU_CONFERENCE_2023, 'login_type': 'native', } @@ -103,7 +103,7 @@ def get_campaigns(): newest_campaigns.update({ 'agu_conference': { 'system_tag': CampaignSourceTags.AguConference.value, - 'redirect_url': furl(DOMAIN).add(path='dashboard/').url, + 'redirect_url': furl(DOMAIN).add(path='my_projects/').url, 'confirmation_email_template': mails.CONFIRM_EMAIL_AGU_CONFERENCE, 'login_type': 'native', } diff --git a/framework/auth/views.py b/framework/auth/views.py index 590575b8f73..50ef12a77e6 100644 --- a/framework/auth/views.py +++ b/framework/auth/views.py @@ -35,8 +35,6 @@ from osf.models.tag import Tag from osf.utils.requests import check_select_for_update from website.util.metrics import CampaignClaimedTags, CampaignSourceTags -from website.ember_osf_web.decorators import ember_flag_is_active -from osf import features @block_bing_preview @@ -85,8 +83,8 @@ def _reset_password_get(auth, uid=None, token=None, institutional=False): } raise HTTPError(http_status.HTTP_400_BAD_REQUEST, data=error_data) - # override routes.py login_url to redirect to dashboard - service_url = web_url_for('dashboard', _absolute=True) + # override routes.py login_url to redirect to myprojects + service_url = web_url_for('my_projects', _absolute=True) return { 'uid': user_obj._id, @@ -176,9 +174,9 @@ def forgot_password_get(auth): if auth.logged_in: return auth_logout(redirect_url=request.url) - #overriding the routes.py sign in url to redirect to the dashboard after login + #overriding the routes.py sign in url to redirect to the myprojects after login context = {} - context['login_url'] = web_url_for('dashboard', _absolute=True) + context['login_url'] = web_url_for('my_projects', _absolute=True) return context @@ -322,7 +320,7 @@ def login_and_register_handler(auth, login=True, campaign=None, next_url=None, l # unlike other campaigns, institution login serves as an alternative for authentication if campaign == 'institution': if next_url is None: - next_url = web_url_for('dashboard', _absolute=True) + next_url = web_url_for('my_projects', _absolute=True) data['status_code'] = http_status.HTTP_302_FOUND if auth.logged_in: data['next_url'] = next_url @@ -389,7 +387,7 @@ def login_and_register_handler(auth, login=True, campaign=None, next_url=None, l # `/login/` or `/register/` without any parameter if auth.logged_in: data['status_code'] = http_status.HTTP_302_FOUND - data['next_url'] = web_url_for('dashboard', _absolute=True) + data['next_url'] = web_url_for('my_projects', _absolute=True) return data @@ -406,7 +404,7 @@ def auth_login(auth): if campaign and logged out, go to campaign register page (with next_url if presents) if next_url and logged in, go to next url if next_url and logged out, go to cas login page with current request url as service parameter - if none, go to `/dashboard` which is decorated by `@must_be_logged_in` + if none, go to `/myprojects` which is decorated by `@must_be_logged_in` :param auth: the auth context :return: redirects @@ -421,7 +419,6 @@ def auth_login(auth): @collect_auth -@ember_flag_is_active(features.EMBER_AUTH_REGISTER) def auth_register(auth): """ View for OSF register. Land on the register page, redirect or go to `auth_logout` @@ -434,7 +431,7 @@ def auth_register(auth): if next_url and logged in, go to next url if next_url and logged out, go to cas login page with current request url as service parameter if next_url and logout flag, log user out first and then go to the next_url - if none, go to `/dashboard` which is decorated by `@must_be_logged_in` + if none, go to `/myprojects` which is decorated by `@must_be_logged_in` :param auth: the auth context :return: land, redirect or `auth_logout` @@ -544,7 +541,7 @@ def auth_email_logout(token, user): When a user is adding an email or merging an account, add the email to the user and log them out. """ - redirect_url = cas.get_logout_url(service_url=cas.get_login_url(service_url=web_url_for('index', _absolute=True))) + redirect_url = cas.get_logout_url(service_url=cas.get_login_url(service_url=web_url_for('auth_login', _absolute=True))) try: unconfirmed_email = user.get_unconfirmed_email_for_token(token) except InvalidTokenError: @@ -613,7 +610,7 @@ def external_login_confirm_email_get(auth, uid, token): return redirect(campaign_url) if new: status.push_status_message(language.WELCOME_MESSAGE, kind='default', jumbotron=True, trust=True, id='welcome_message') - return redirect(web_url_for('dashboard')) + return redirect(web_url_for('my_projects')) # token is invalid if token not in user.email_verifications: @@ -711,7 +708,7 @@ def confirm_email_get(token, auth=None, **kwargs): status.push_status_message(language.WELCOME_MESSAGE, kind='default', jumbotron=True, trust=True, id='welcome_message') if token in auth.user.email_verifications: status.push_status_message(language.CONFIRM_ALTERNATE_EMAIL_ERROR, kind='danger', trust=True, id='alternate_email_error') - return redirect(web_url_for('index')) + return redirect(web_url_for('my_projects')) status.push_status_message(language.MERGE_COMPLETE, kind='success', trust=False) return redirect(web_url_for('user_account')) @@ -991,7 +988,7 @@ def resend_confirmation_post(auth): try: send_confirm_email(user, clean_email, renew=True) except KeyError: - # already confirmed, redirect to dashboard + # already confirmed, redirect to myprojects status_message = f'This email {clean_email} has already been confirmed.' kind = 'warning' user.email_last_sent = timezone.now() @@ -1051,7 +1048,7 @@ def external_login_email_post(): service_url = session.get('service_url', None) # TODO: @cslzchen use user tags instead of destination - destination = 'dashboard' + destination = 'my_projects' for campaign in campaigns.get_campaigns(): if campaign != 'institution': # Handle different url encoding schemes between `furl` and `urlparse/urllib`. diff --git a/framework/sessions/__init__.py b/framework/sessions/__init__.py index 21dc850cb53..5891cb6d69f 100644 --- a/framework/sessions/__init__.py +++ b/framework/sessions/__init__.py @@ -216,7 +216,7 @@ def before_request(): try: user_session = flask_get_session_from_cookie(cookie) except InvalidCookieOrSessionError: - response = redirect(web_url_for('index')) + response = redirect(web_url_for('auth_login')) response.delete_cookie(settings.COOKIE_NAME, domain=settings.OSF_COOKIE_DOMAIN) return response # Case 1: anonymous session that is used for first time external (e.g. ORCiD) login only diff --git a/osf/features.yaml b/osf/features.yaml index a376edc851d..f70e7d10922 100644 --- a/osf/features.yaml +++ b/osf/features.yaml @@ -9,7 +9,7 @@ # 3. Use the admin app to enable/disable the flag/switch at your convenience # 4. When feature is complete add the activity status (active or everyone) to the value it will have in production until # the old flipping code can be removed. -# 5. When a flag name is no longer referenced anywhere in this repo or in the Ember app remove it from this list. +# 5. When a flag name is no longer referenced anywhere in this repo remove it from this list. flags: - flag_name: MANUAL_DOI_AND_GUID @@ -21,18 +21,7 @@ flags: - flag_name: ENABLE_GV name: gravy_waffle note: This is used to enable GravyValet, the system responsible for addons, this will remove the files widget on the - project overview page. Will be used with EMBER_USER_SETTINGS_ADDONS and EMBER_NODE_SETTINGS_ADDONS to flip all - UI elements to the new addons system. - everyone: true - - - flag_name: EMBER_FILE_PROJECT_DETAIL - name: ember_file_project_detail_page - note: This is part of the upcoming files page redesign - everyone: true - - - flag_name: EMBER_PROJECT_FILES - name: ember_project_files_page - note: This is part of the upcoming files page redesign + project overview page. everyone: true - flag_name: STORAGE_USAGE @@ -60,136 +49,6 @@ flags: note: Indicates whether EGAP admins have special access to custom schemas everyone: true - - flag_name: EMBER_AUTH_REGISTER - name: ember_auth_register - note: This indicates whether this view is routed for OSF register, redirect or go to `auth_logout` - everyone: true - - - flag_name: EMBER_PROJECT_DETAIL - name: ember_project_detail_page - note: This flag controls whether the project overview page is routed to the ember app - everyone: false - - - flag_name: EMBER_CREATE_DRAFT_REGISTRATION - name: ember_create_draft_registration_page - note: This flag controls whether POST requests to /project//registrations/ and - /project//node//registrations/ are routed to the ember app - everyone: false - - - flag_name: EMBER_MEETING_DETAIL - name: ember_meeting_detail_page - note: This flag controls whether the `conference_results` view routes to the Ember app - everyone: true - - - flag_name: EMBER_MY_PROJECTS - name: ember_my_projects_page - note: This flag controls whether the `My Projects Page` view routes to the Ember app - everyone: false - - - flag_name: EMBER_PROJECT_CONTRIBUTORS - name: ember_project_contributors_page - note: This flag controls whether the `Node Contributor Page` view routes to the Ember app - everyone: false - - - flag_name: EMBER_PROJECT_SETTINGS - name: ember_project_settings_page - note: This flag controls whether the `Node Settings Page` view routes to the Ember app - everyone: false - - - flag_name: EMBER_PROJECT_WIKI - name: ember_project_wiki_page - note: This flag controls whether the `Project Wiki Home Page` view routes to the Ember app - everyone: false - - - flag_name: EMBER_REGISTRATION_FORM_DETAIL - name: ember_registration_form_detail_page - note: This flag controls whether the `Node Register Template Page` view routes to the Ember app - everyone: false - - - flag_name: EMBER_SEARCH_PAGE - name: ember_search_page - note: This flag controls whether the `Search Page` view routes to the Ember app - everyone: true - - - flag_name: EMBER_USER_PROFILE - name: ember_user_profile_page - note: This flag controls whether the `User Profile Page` view routes to the Ember app - everyone: false - - - flag_name: EMBER_USER_SETTINGS - name: ember_user_settings_page - note: This flag controls whether the `User Settings Page` view routes to the Ember app - everyone: false - - - flag_name: EMBER_USER_SETTINGS_NOTIFICATIONS - name: ember_user_settings_notifications_page - note: This flag controls whether the `User Notifications Page` view routes to the Ember app - everyone: false - - - flag_name: EMBER_MEETINGS - name: ember_meetings_page - note: This is complete and should be permanently on. - everyone: true - - - flag_name: EMBER_EDIT_DRAFT_REGISTRATION - name: ember_edit_draft_registration_page - note: This is complete and should be permanently on. - everyone: true - - - flag_name: EMBER_FILE_REGISTRATION_DETAIL - name: ember_file_registration_detail_page - note: This is complete and should be permanently on. - everyone: true - - - flag_name: EMBER_REGISTRATION_FILES - name: ember_registration_files_page - note: This is complete and should be permanently on. - everyone: true - - - flag_name: EMBER_REGISTRIES_DETAIL_PAGE - name: ember_registries_detail_page - note: This is complete and should be permanently on. - everyone: true - - - flag_name: EMBER_USER_SETTINGS_ACCOUNTS - name: ember_user_settings_account_page - note: This is complete and should be permanently on. - everyone: true - - - flag_name: EMBER_USER_SETTINGS_APPS - name: ember_user_settings_apps_page - note: This is complete and should be permanently on. - everyone: true - - - flag_name: EMBER_USER_SETTINGS_TOKENS - name: ember_user_settings_tokens_page - note: This is complete and should be permanently on. - everyone: true - - - flag_name: EMBER_AB_TESTING_HOME_PAGE_VERSION_B - name: ab_testing_home_page_version_b - note: This is no longer used. - - - flag_name: EMBER_AB_TESTING_HOME_PAGE_HERO_TEXT_VERSION_B - name: ab_testing_home_page_hero_text_version_b - note: This is no longer used. - everyone: true - - - flag_name: EMBER_PROJECT_ANALYTICS - name: ember_project_analytics_page - note: This is no longer used. - everyone: false - - - flag_name: EMBER_PROJECT_FORKS - name: ember_project_forks_page - note: This is no longer used. - everyone: false - - - flag_name: EMBER_PROJECT_REGISTRATIONS - name: ember_project_registrations_page - note: This is no longer used. - everyone: false - - flag_name: ENABLE_CHRONOS name: enable_chronos note: This is not used diff --git a/osf_tests/test_guid.py b/osf_tests/test_guid.py index fb825261906..276ceecb05a 100644 --- a/osf_tests/test_guid.py +++ b/osf_tests/test_guid.py @@ -1,14 +1,11 @@ from unittest import mock -from urllib.parse import quote -from django.utils import timezone from django.core.exceptions import MultipleObjectsReturned import pytest from framework.auth import Auth from osf.models import Guid, GuidVersionsThrough, NodeLicenseRecord, OSFUser, Preprint from osf.models.base import VersionedGuidMixin -from osf.utils.permissions import ADMIN from osf_tests.factories import ( AuthUserFactory, NodeFactory, @@ -19,8 +16,6 @@ UserFactory, ) from tests.base import OsfTestCase -from tests.test_websitefiles import TestFile -from website.settings import MFR_SERVER_URL, WATERBUTLER_URL @pytest.mark.django_db @@ -234,236 +229,6 @@ def test_resolve_guid_private_request_access_or_redirect_to_cas(self): assert res.status_code == 403 assert 'OSF | Request Access' in res.text - def test_resolve_guid_download_file(self): - pp = PreprintFactory(finish=True) - - res = self.app.get(pp.url + 'download') - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=1' in res.location - - res = self.app.get(pp.url + 'download/') - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=1' in res.location - - res = self.app.get(f'/{pp.primary_file.get_guid(create=True)._id}/download') - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=1' in res.location - - pp.primary_file.create_version( - creator=pp.creator, - location={'folder': 'osf', 'object': 'deadbe', 'service': 'cloud'}, - metadata={'contentType': 'img/png', 'size': 9001} - ) - pp.primary_file.save() - - res = self.app.get(pp.url + 'download/') - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=2' in res.location - - res = self.app.get(pp.url + 'download/?version=1') - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?version=1&action=download&direct' in res.location - - unpub_pp = PreprintFactory(project=self.node, is_published=False) - res = self.app.get(unpub_pp.url + 'download/?version=1', auth=unpub_pp.creator.auth) - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{unpub_pp._id}/providers/{unpub_pp.primary_file.provider}{unpub_pp.primary_file.path}?version=1&action=download&direct' in res.location - - @mock.patch('website.settings.USE_EXTERNAL_EMBER', True) - @mock.patch('website.settings.EXTERNAL_EMBER_APPS', { - 'preprints': { - 'server': 'http://localhost:4200', - 'path': '/preprints/' - }, - }) - def test_resolve_guid_download_file_from_emberapp_preprints(self): - provider = PreprintProviderFactory(_id='sockarxiv', name='Sockarxiv') - pp = PreprintFactory(finish=True, provider=provider) - assert pp.url.startswith('/preprints/sockarxiv') - - res = self.app.get(pp.url + 'download') - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=1' in res.location - - res = self.app.get(pp.url + 'download/') - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=1' in res.location - - @mock.patch('website.settings.USE_EXTERNAL_EMBER', True) - @mock.patch('website.settings.EXTERNAL_EMBER_APPS', { - 'preprints': { - 'server': 'http://localhost:4200', - 'path': '/preprints/' - }, - }) - def test_resolve_guid_download_file_from_emberapp_preprints_unpublished(self): - # non-branded domains - provider = PreprintProviderFactory(_id='sockarxiv', name='Sockarxiv', reviews_workflow='pre-moderation') - - # branded domains - branded_provider = PreprintProviderFactory(_id='spot', name='Spotarxiv', reviews_workflow='pre-moderation') - branded_provider.allow_submissions = False - branded_provider.domain = 'https://www.spotarxiv.com' - branded_provider.description = 'spots not dots' - branded_provider.domain_redirect_enabled = True - branded_provider.share_publish_type = 'Thesis' - branded_provider.save() - - # test_provider_submitter_can_download_unpublished - submitter = AuthUserFactory() - pp = PreprintFactory(finish=True, provider=provider, is_published=False, creator=submitter) - pp.run_submit(submitter) - pp_branded = PreprintFactory(finish=True, provider=branded_provider, is_published=False, filename='preprint_file_two.txt', creator=submitter) - pp_branded.run_submit(submitter) - - res = self.app.get(f'{pp.url}download', auth=submitter.auth) - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=1' in res.location - - res = self.app.get(f'{pp_branded.url}download', auth=submitter.auth) - assert res.status_code == 302 - - # test_provider_super_user_can_download_unpublished - super_user = AuthUserFactory() - super_user.is_superuser = True - super_user.save() - - res = self.app.get(f'{pp.url}download', auth=super_user.auth) - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=1' in res.location - - res = self.app.get(f'{pp_branded.url}download', auth=super_user.auth) - assert res.status_code == 302 - - # test_provider_moderator_can_download_unpublished - moderator = AuthUserFactory() - provider.add_to_group(moderator, 'moderator') - provider.save() - - res = self.app.get(f'{pp.url}download', auth=moderator.auth) - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=1' in res.location - - branded_provider.add_to_group(moderator, 'moderator') - branded_provider.save() - - res = self.app.get(f'{pp_branded.url}download', auth=moderator.auth) - assert res.status_code == 302 - - # test_provider_admin_can_download_unpublished - admin = AuthUserFactory() - provider.add_to_group(admin, ADMIN) - provider.save() - - res = self.app.get(f'{pp.url}download', auth=admin.auth) - assert res.status_code == 302 - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?action=download&direct&version=1' in res.location - - branded_provider.add_to_group(admin, ADMIN) - branded_provider.save() - - res = self.app.get(f'{pp_branded.url}download', auth=admin.auth) - assert res.status_code == 302 - - def test_resolve_guid_download_file_export(self): - pp = PreprintFactory(finish=True) - - res = self.app.get(pp.url + 'download?format=asdf') - assert res.status_code == 302 - assert f'{MFR_SERVER_URL}/export?format=asdf&url=' in res.location - assert f'{quote(WATERBUTLER_URL)}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}%3Fformat%3Dasdf%26action%3Ddownload%26direct%26version%3D1' in res.location - - res = self.app.get(pp.url + 'download/?format=asdf') - assert res.status_code == 302 - assert f'{MFR_SERVER_URL}/export?format=asdf&url=' in res.location - assert f'{quote(WATERBUTLER_URL)}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}%3Fformat%3Dasdf%26action%3Ddownload%26direct%26version%3D1' in res.location - - res = self.app.get(f'/{pp.primary_file.get_guid(create=True)._id}/download?format=asdf') - assert res.status_code == 302 - assert f'{MFR_SERVER_URL}/export?format=asdf&url=' in res.location - - assert f'{quote(WATERBUTLER_URL)}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}%3Fformat%3Dasdf%26action%3Ddownload%26direct%26version%3D1' in res.location - - res = self.app.get(f'/{pp.primary_file.get_guid(create=True)._id}/download/?format=asdf') - assert res.status_code == 302 - assert f'{MFR_SERVER_URL}/export?format=asdf&url=' in res.location - - assert f'{quote(WATERBUTLER_URL)}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}%3Fformat%3Dasdf%26action%3Ddownload%26direct%26version%3D1' in res.location - - pp.primary_file.create_version( - creator=pp.creator, - location={'folder': 'osf', 'object': 'deadbe', 'service': 'cloud'}, - metadata={'contentType': 'img/png', 'size': 9001} - ) - pp.primary_file.save() - - res = self.app.get(pp.url + 'download/?format=asdf') - assert res.status_code == 302 - assert f'{MFR_SERVER_URL}/export?format=asdf&url=' in res.location - assert f'{quote(WATERBUTLER_URL)}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}%3F' in res.location - quarams = res.location.split('%3F')[1].split('%26') - assert 'action%3Ddownload' in quarams - assert 'version%3D2' in quarams - assert 'direct' in quarams - - res = self.app.get(pp.url + 'download/?format=asdf&version=1') - assert res.status_code == 302 - assert f'{MFR_SERVER_URL}/export?format=asdf&url=' in res.location - assert f'{quote(WATERBUTLER_URL)}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}%3F' in res.location - quarams = res.location.split('%3F')[1].split('%26') - assert 'action%3Ddownload' in quarams - assert 'version%3D1' in quarams - assert 'direct' in quarams - - unpub_pp = PreprintFactory(project=self.node, is_published=False) - res = self.app.get(unpub_pp.url + 'download?format=asdf', auth=unpub_pp.creator.auth) - assert res.status_code == 302 - assert res.status_code == 302 - assert f'{MFR_SERVER_URL}/export?format=asdf&url=' in res.location - assert f'{quote(WATERBUTLER_URL)}/v1/resources/{unpub_pp._id}/providers/{unpub_pp.primary_file.provider}{unpub_pp.primary_file.path}%3F' in res.location - quarams = res.location.split('%3F')[1].split('%26') - assert 'action%3Ddownload' in quarams - assert 'version%3D1' in quarams - assert 'direct' in quarams - - def test_resolve_guid_download_file_export_same_format_optimization(self): - pp = PreprintFactory(filename='test.pdf', finish=True) - - res = self.app.get(pp.url + 'download/?format=pdf') - assert res.status_code == 302 - assert f'{MFR_SERVER_URL}/export?' not in res.location - assert f'{WATERBUTLER_URL}/v1/resources/{pp._id}/providers/{pp.primary_file.provider}{pp.primary_file.path}?format=pdf&action=download&direct&version=1' in res.location - - def test_resolve_guid_download_errors(self): - testfile = TestFile.get_or_create(self.node, 'folder/path') - testfile.name = 'asdf' - testfile.materialized_path = '/folder/path' - guid = testfile.get_guid(create=True) - testfile.save() - testfile.delete() - res = self.app.get(f'/{guid}/download') - assert res.status_code == 404 - - pp = PreprintFactory(is_published=False) - res = self.app.get(pp.url + 'download') - assert res.status_code == 404 - - pp.is_published = True - pp.save() - pp.is_public = False - pp.save() - - non_contrib = AuthUserFactory() - - res = self.app.get(pp.url + 'download', auth=non_contrib.auth) - assert res.status_code == 403 - - pp.deleted = timezone.now() - pp.save() - - res = self.app.get(pp.url + 'download', auth=non_contrib.auth) - assert res.status_code == 410 - def test_resolve_guid_redirect_to_versioned_guid(self): pp = PreprintFactory(filename='test.pdf', finish=True) diff --git a/osf_tests/test_user.py b/osf_tests/test_user.py index 41314641810..4c430ea988c 100644 --- a/osf_tests/test_user.py +++ b/osf_tests/test_user.py @@ -470,8 +470,8 @@ def test_add_blocked_domain_unconfirmed_email(self, user): def test_get_confirmation_url_for_external_service(self, random_string): random_string.return_value = 'abcde' u = UnconfirmedUserFactory() - assert (u.get_confirmation_url(u.username, external_id_provider='service', destination='dashboard') == - f'{settings.DOMAIN}confirm/external/{u._id}/abcde/?destination=dashboard') + assert (u.get_confirmation_url(u.username, external_id_provider='service', destination='my_projects') == + f'{settings.DOMAIN}confirm/external/{u._id}/abcde/?destination=my_projects') @mock.patch('website.security.random_string') def test_get_confirmation_token(self, random_string): diff --git a/tests/test_addons.py b/tests/test_addons.py index 4c5d3f93f55..c202b680183 100644 --- a/tests/test_addons.py +++ b/tests/test_addons.py @@ -1,7 +1,6 @@ import datetime import time import functools -import logging from importlib import import_module from unittest.mock import Mock @@ -16,13 +15,12 @@ from framework.auth.core import Auth from framework.exceptions import HTTPError from framework.sessions import get_session -from tests.base import OsfTestCase, get_default_metaschema +from tests.base import OsfTestCase from api_tests.utils import create_test_file from osf_tests.factories import ( AuthUserFactory, ProjectFactory, RegistrationFactory, - DraftRegistrationFactory, ) from website import settings from addons.base import views @@ -31,7 +29,6 @@ from addons.github.tests.factories import GitHubAccountFactory from addons.osfstorage.models import OsfStorageFileNode, OsfStorageFolder, OsfStorageFile from addons.osfstorage.tests.factories import FileVersionFactory -from osf import features from osf.models import files as file_models from osf.models.files import BaseFileNode, TrashedFileNode from osf.utils.permissions import WRITE, READ @@ -44,10 +41,6 @@ from api.caching.utils import storage_usage_cache from dateutil.parser import parse as parse_date from framework import sentry -from api.base.settings.defaults import API_BASE -from tests.json_api_test_app import JSONAPITestApp -from website.settings import EXTERNAL_EMBER_APPS -from waffle.testutils import override_flag from django.conf import settings as django_conf_settings SessionStore = import_module(django_conf_settings.SESSION_ENGINE).SessionStore @@ -1317,7 +1310,7 @@ def test_redirects_to_guid(self): ) assert resp.status_code == 302 - assert resp.location == f'/{guid._id}/' + assert resp.location == f'{settings.DOMAIN}{guid._id}/' def test_action_download_redirects_to_download_with_param(self): file_node = self.get_test_file() @@ -1360,40 +1353,6 @@ def test_action_download_redirects_to_download_with_version(self): # Note: version is added but us but all other url params are added as well assert_urls_equal(location.url, file_node.generate_waterbutler_url(action='download', direct=None, revision=1, version='')) - @mock.patch('website.views.stream_emberapp') - @pytest.mark.enable_bookmark_creation - def test_action_view_calls_view_file(self, mock_ember): - self.user.reload() - self.project.reload() - - file_node = self.get_test_file() - guid = file_node.get_guid(create=True) - - with override_flag(features.EMBER_FILE_PROJECT_DETAIL, active=True): - self.app.get(f'/{guid._id}/?action=view', auth=self.user.auth) - - args, kwargs = mock_ember.call_args - assert kwargs == {} - assert args[0] == EXTERNAL_EMBER_APPS['ember_osf_web']['server'] - assert args[1] == EXTERNAL_EMBER_APPS['ember_osf_web']['path'].rstrip('/') - - @mock.patch('website.views.stream_emberapp') - @pytest.mark.enable_bookmark_creation - def test_no_action_calls_view_file(self, mock_ember): - self.user.reload() - self.project.reload() - - file_node = self.get_test_file() - guid = file_node.get_guid(create=True) - - with override_flag(features.EMBER_FILE_PROJECT_DETAIL, active=True): - self.app.get(f'/{guid._id}/', auth=self.user.auth) - - args, kwargs = mock_ember.call_args - assert kwargs == {} - assert args[0] == EXTERNAL_EMBER_APPS['ember_osf_web']['server'] - assert args[1] == EXTERNAL_EMBER_APPS['ember_osf_web']['path'].rstrip('/') - def test_download_create_guid(self): file_node = self.get_test_file() assert file_node.get_guid() is None @@ -1462,30 +1421,19 @@ def test_nonstorage_addons_raise(self): ) assert resp.status_code == 400 - @mock.patch('website.views.stream_emberapp') - def test_head_returns_url_and_redirect(self, mock_ember): + def test_head_returns_url_and_redirect(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) - with override_flag(features.EMBER_FILE_PROJECT_DETAIL, active=True): - resp = self.app.head(f'/{guid._id}/', auth=self.user.auth) - assert resp.status_code == 200 - - args, kwargs = mock_ember.call_args - assert kwargs == {} - assert args[0] == EXTERNAL_EMBER_APPS['ember_osf_web']['server'] - assert args[1] == EXTERNAL_EMBER_APPS['ember_osf_web']['path'].rstrip('/') - + resp = self.app.head(f'/{guid._id}/', auth=self.user.auth) + assert resp.status_code == 302 def test_head_returns_url_with_version_and_redirect(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head(f'/{guid._id}/?revision=1&foo=bar', auth=self.user.auth) - location = furl(resp.location) - # Note: version is added but us but all other url params are added as well assert resp.status_code == 302 - assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version='', foo='bar')) def test_nonexistent_addons_raise(self): path = 'cloudfiles' @@ -1523,26 +1471,6 @@ def test_unauth_addons_raise(self): self.assertEqual(resp.status_code, 401) assert resp.status_code == 401 - def test_resolve_folder_raise(self): - folder = OsfStorageFolder( - name='folder', - target=self.project, - path='/test/folder/', - materialized_path='/test/folder/', - ) - folder.save() - resp = self.app.get( - self.project.web_url_for( - 'addon_view_or_download_file', - path=folder._id, - provider='osfstorage', - ), - auth=self.user.auth, - - ) - - assert resp.status_code == 400 - def test_delete_action_creates_trashed_file_node(self): file_node = self.get_test_file() payload = { diff --git a/tests/test_auth.py b/tests/test_auth.py index 892986e8910..99d4465e70a 100644 --- a/tests/test_auth.py +++ b/tests/test_auth.py @@ -106,7 +106,7 @@ def test_confirm_email(self): res = self.app.resolve_redirect(res) assert res.status_code == 302 - assert '/' == urlparse(res.location).path + assert '/myprojects/' == urlparse(res.location).path assert len(self.mock_send_grid.call_args_list) == 0 # assert len(get_session()['status']) == 1 @@ -124,7 +124,7 @@ def test_get_user_with_wrong_password_returns_false(self): assert not auth.get_user(email=user.username, password='wrong') def test_get_user_by_external_info(self): - service_url = 'http://localhost:5000/dashboard/' + service_url = 'http://localhost:5000/my_projects/' user, validated_credentials, cas_resp = generate_external_user_with_resp(service_url) user.save() assert auth.get_user(external_id_provider=validated_credentials['provider'], external_id=validated_credentials['id']) == user @@ -133,7 +133,7 @@ def test_get_user_by_external_info(self): @mock.patch('framework.auth.cas.CasClient.service_validate') def test_successful_external_login_cas_redirect(self, mock_service_validate, mock_get_user_from_cas_resp): # TODO: check in qa url encoding - service_url = 'http://localhost:5000/dashboard/' + service_url = 'http://localhost:5000/my_projects/' user, validated_credentials, cas_resp = generate_external_user_with_resp(service_url) mock_service_validate.return_value = cas_resp mock_get_user_from_cas_resp.return_value = (user, validated_credentials, 'authenticate') @@ -148,7 +148,7 @@ def test_successful_external_login_cas_redirect(self, mock_service_validate, moc @mock.patch('framework.auth.cas.get_user_from_cas_resp') @mock.patch('framework.auth.cas.CasClient.service_validate') def test_successful_external_first_login(self, mock_service_validate, mock_get_user_from_cas_resp): - service_url = 'http://localhost:5000/dashboard/' + service_url = 'http://localhost:5000/my_projects/' _, validated_credentials, cas_resp = generate_external_user_with_resp(service_url, user=False) mock_service_validate.return_value = cas_resp mock_get_user_from_cas_resp.return_value = (None, validated_credentials, 'external_first_login') @@ -161,7 +161,7 @@ def test_successful_external_first_login(self, mock_service_validate, mock_get_u @mock.patch('framework.auth.cas.get_user_from_cas_resp') @mock.patch('framework.auth.cas.CasClient.service_validate') def test_successful_external_first_login_without_attributes(self, mock_service_validate, mock_get_user_from_cas_resp, mock_external_first_login_authenticate): - service_url = 'http://localhost:5000/dashboard/' + service_url = 'http://localhost:5000/my_projects/' user, validated_credentials, cas_resp = generate_external_user_with_resp(service_url, user=False, release=False) mock_service_validate.return_value = cas_resp mock_get_user_from_cas_resp.return_value = (None, validated_credentials, 'external_first_login') diff --git a/tests/test_auth_basic_auth.py b/tests/test_auth_basic_auth.py index bad44316bfa..e1b9d6e5b8d 100644 --- a/tests/test_auth_basic_auth.py +++ b/tests/test_auth_basic_auth.py @@ -99,4 +99,4 @@ def test_expired_cookie(self): self.app.set_cookie(settings.COOKIE_NAME, str(cookie)) res = self.app.get(self.reachable_url) assert res.status_code == 302 - assert '/' == res.location + assert '/login/' == res.location diff --git a/tests/test_auth_views.py b/tests/test_auth_views.py index 8fe2b0ac12e..ba92e202374 100644 --- a/tests/test_auth_views.py +++ b/tests/test_auth_views.py @@ -551,25 +551,25 @@ def test_osf_login_with_auth(self): # login: user with auth data = login_and_register_handler(self.auth) assert data.get('status_code') == http_status.HTTP_302_FOUND - assert data.get('next_url') == web_url_for('dashboard', _absolute=True) + assert data.get('next_url') == web_url_for('my_projects', _absolute=True) def test_osf_login_without_auth(self): # login: user without auth data = login_and_register_handler(self.no_auth) assert data.get('status_code') == http_status.HTTP_302_FOUND - assert data.get('next_url') == web_url_for('dashboard', _absolute=True) + assert data.get('next_url') == web_url_for('my_projects', _absolute=True) def test_osf_register_with_auth(self): # register: user with auth data = login_and_register_handler(self.auth, login=False) assert data.get('status_code') == http_status.HTTP_302_FOUND - assert data.get('next_url') == web_url_for('dashboard', _absolute=True) + assert data.get('next_url') == web_url_for('my_projects', _absolute=True) def test_osf_register_without_auth(self): # register: user without auth data = login_and_register_handler(self.no_auth, login=False) assert data.get('status_code') == http_status.HTTP_200_OK - assert data.get('next_url') == web_url_for('dashboard', _absolute=True) + assert data.get('next_url') == web_url_for('my_projects', _absolute=True) def test_next_url_login_with_auth(self): # next_url login: user with auth @@ -603,13 +603,13 @@ def test_institution_login_with_auth(self): # institution login: user with auth data = login_and_register_handler(self.auth, campaign='institution') assert data.get('status_code') == http_status.HTTP_302_FOUND - assert data.get('next_url') == web_url_for('dashboard', _absolute=True) + assert data.get('next_url') == web_url_for('my_projects', _absolute=True) def test_institution_login_without_auth(self): # institution login: user without auth data = login_and_register_handler(self.no_auth, campaign='institution') assert data.get('status_code') == http_status.HTTP_302_FOUND - assert data.get('next_url') == cas.get_login_url(web_url_for('dashboard', _absolute=True), + assert data.get('next_url') == cas.get_login_url(web_url_for('my_projects', _absolute=True), campaign='institution') def test_institution_login_next_url_with_auth(self): @@ -628,13 +628,13 @@ def test_institution_register_with_auth(self): # institution register: user with auth data = login_and_register_handler(self.auth, login=False, campaign='institution') assert data.get('status_code') == http_status.HTTP_302_FOUND - assert data.get('next_url') == web_url_for('dashboard', _absolute=True) + assert data.get('next_url') == web_url_for('my_projects', _absolute=True) def test_institution_register_without_auth(self): # institution register: user without auth data = login_and_register_handler(self.no_auth, login=False, campaign='institution') assert data.get('status_code') == http_status.HTTP_302_FOUND - assert data.get('next_url') == cas.get_login_url(web_url_for('dashboard', _absolute=True), campaign='institution') + assert data.get('next_url') == cas.get_login_url(web_url_for('my_projects', _absolute=True), campaign='institution') def test_campaign_login_with_auth(self): for campaign in get_campaigns(): @@ -775,7 +775,7 @@ def setUp(self): super().setUp() self.goodbye_url = web_url_for('goodbye', _absolute=True) self.redirect_url = web_url_for('forgot_password_get', _absolute=True) - self.valid_next_url = web_url_for('dashboard', _absolute=True) + self.valid_next_url = web_url_for('my_projects', _absolute=True) self.invalid_next_url = 'http://localhost:1234/abcde' self.auth_user = AuthUserFactory() diff --git a/tests/test_campaigns.py b/tests/test_campaigns.py index 1df6a32169a..221ce03f8cf 100644 --- a/tests/test_campaigns.py +++ b/tests/test_campaigns.py @@ -238,7 +238,7 @@ def setUp(self): super().setUp() self.url_login = web_url_for('auth_login', campaign='institution') self.url_register = web_url_for('auth_register', campaign='institution') - self.service_url = web_url_for('dashboard', _absolute=True) + self.service_url = web_url_for('my_projects', _absolute=True) # go to CAS institution login page if not logged in def test_institution_not_logged_in(self): diff --git a/tests/test_comfirmation_view_block_bing.py b/tests/test_comfirmation_view_block_bing.py index 8ef5290b6e3..bfb207272aa 100644 --- a/tests/test_comfirmation_view_block_bing.py +++ b/tests/test_comfirmation_view_block_bing.py @@ -152,7 +152,7 @@ def test_external_login_confirm_email_get_create_user(self): create_url = user.get_confirmation_url( user.username, external_id_provider='service', - destination='dashboard' + destination='my_projects' ) res = self.app.get( @@ -179,7 +179,7 @@ def test_external_login_confirm_email_get_link_user(self): link_url = user.get_confirmation_url( user.username, external_id_provider='service', - destination='dashboard' + destination='my_projects' ) res = self.app.get( diff --git a/tests/test_ember_osf_web.py b/tests/test_ember_osf_web.py deleted file mode 100644 index 31868132fb7..00000000000 --- a/tests/test_ember_osf_web.py +++ /dev/null @@ -1,59 +0,0 @@ -from unittest import mock -from flask import request - -from tests.base import OsfTestCase -from website.ember_osf_web.decorators import ember_flag_is_active -from osf_tests.factories import FlagFactory, UserFactory - -from django.contrib.auth.models import Group - - -class TestEmberFlagIsActive(OsfTestCase): - - def setUp(self): - super().setUp() - self.flag = FlagFactory(name='active_flag') - FlagFactory(name='inactive_flag', everyone=False).save() - self.mock_func = lambda: 'test value' - - @mock.patch('website.ember_osf_web.decorators.use_ember_app') - def test_use_ember_app(self, mock_use_ember_app): - ember_flag_is_active('active_flag')(self.mock_func)() - - mock_use_ember_app.assert_called_with() - - @mock.patch('website.ember_osf_web.decorators.use_ember_app') - def test_dont_use_ember_app(self, mock_use_ember_app): - # mock over external module 'waffle.flag_is_active` not ours - - ember_flag_is_active('inactive_flag')(self.mock_func)() - - assert not mock_use_ember_app.called - - @mock.patch('api.waffle.utils._get_current_user') - @mock.patch('website.ember_osf_web.decorators.flag_is_active') - @mock.patch('website.ember_osf_web.decorators.use_ember_app') - def test_ember_flag_is_active_authenticated_user(self, mock_use_ember_app, mock_flag_is_active, mock__get_current_user): - # mock over external module 'waffle.flag_is_active` not ours - - user = UserFactory() - mock__get_current_user.return_value = user - - ember_flag_is_active('active_flag')(self.mock_func)() - - mock_flag_is_active.assert_called_with(request, 'active_flag') - mock_use_ember_app.assert_called_with() - - @mock.patch('api.waffle.utils._get_current_user', return_value=None) - @mock.patch('website.ember_osf_web.decorators.flag_is_active') - @mock.patch('website.ember_osf_web.decorators.use_ember_app') - def test_ember_flag_is_active_unauthenticated_user(self, mock_use_ember_app, mock_flag_is_active, mock__get_current_user): - # mock over external module 'waffle.flag_is_active` not ours - - ember_flag_is_active('active_flag')(self.mock_func)() - group = Group.objects.create(name='foo') - - self.flag.groups.add(group) - - mock_flag_is_active.assert_called_with(request, 'active_flag') - mock_use_ember_app.assert_called_with() diff --git a/tests/test_misc_views.py b/tests/test_misc_views.py index 814ab0556f1..f616c01194e 100644 --- a/tests/test_misc_views.py +++ b/tests/test_misc_views.py @@ -394,7 +394,7 @@ def test_external_login_email_get_with_invalid_session(self): def test_external_login_confirm_email_get_with_another_user_logged_in(self): # TODO: check in qa url encoding another_user = AuthUserFactory() - url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='dashboard') + url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='my_projects') res = self.app.get(url, auth=another_user.auth) assert res.status_code == 302, 'redirects to cas logout' assert '/logout?service=' in res.location @@ -408,7 +408,7 @@ def test_external_login_confirm_email_get_without_destination(self): def test_external_login_confirm_email_get_create(self): # TODO: check in qa url encoding assert not self.user.is_registered - url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='dashboard') + url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='my_projects') res = self.app.get(url) assert res.status_code == 302, 'redirects to cas login' assert '/login?service=' in res.location @@ -425,7 +425,7 @@ def test_external_login_confirm_email_get_link(self): self.user.external_identity['orcid'][self.provider_id] = 'LINK' self.user.save() assert not self.user.is_registered - url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='dashboard') + url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='my_projects') res = self.app.get(url) assert res.status_code == 302, 'redirects to cas login' assert 'You should be redirected automatically' in str(res.html) @@ -442,7 +442,7 @@ def test_external_login_confirm_email_get_link(self): def test_external_login_confirm_email_get_duped_id(self): dupe_user = UserFactory(external_identity={'orcid': {self.provider_id: 'CREATE'}}) assert dupe_user.external_identity == self.user.external_identity - url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='dashboard') + url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='my_projects') res = self.app.get(url) assert res.status_code == 302, 'redirects to cas login' assert 'You should be redirected automatically' in str(res.html) @@ -458,7 +458,7 @@ def test_external_login_confirm_email_get_duped_id(self): def test_external_login_confirm_email_get_duping_id(self): dupe_user = UserFactory(external_identity={'orcid': {self.provider_id: 'VERIFIED'}}) - url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='dashboard') + url = self.user.get_confirmation_url(self.user.username, external_id_provider='orcid', destination='my_projects') res = self.app.get(url) assert res.status_code == 403, 'only allows one user to link an id' @@ -775,28 +775,10 @@ def test_find_unread_includes_edited_comments(self): n_unread = Comment.find_n_unread(user=user, node=project, page='node') assert n_unread == 1 -@mock.patch('website.views.PROXY_EMBER_APPS', False) class TestResolveGuid(OsfTestCase): def setUp(self): super().setUp() - @mock.patch('website.views.use_ember_app') - def test_preprint_provider_without_domain(self, mock_use_ember_app): - provider = PreprintProviderFactory(domain='') - preprint = PreprintFactory(provider=provider) - url = web_url_for('resolve_guid', _guid=True, guid=preprint._id) - res = self.app.get(url) - mock_use_ember_app.assert_called_with() - - @mock.patch('website.views.use_ember_app') - def test_preprint_provider_with_domain_without_redirect(self, mock_use_ember_app): - domain = 'https://test.com/' - provider = PreprintProviderFactory(_id='test', domain=domain, domain_redirect_enabled=False) - preprint = PreprintFactory(provider=provider) - url = web_url_for('resolve_guid', _guid=True, guid=preprint._id) - res = self.app.get(url) - mock_use_ember_app.assert_called_with() - def test_preprint_provider_with_domain_with_redirect(self): domain = 'https://test.com/' provider = PreprintProviderFactory(_id='test', domain=domain, domain_redirect_enabled=True) @@ -808,11 +790,3 @@ def test_preprint_provider_with_domain_with_redirect(self): assert res.status_code == 301 assert res.headers['location'] == f'{domain}{preprint._id}/' assert res.request.path == f'/{preprint._id}/' - - @mock.patch('website.views.use_ember_app') - def test_preprint_provider_with_osf_domain(self, mock_use_ember_app): - provider = PreprintProviderFactory(_id='osf', domain='https://osf.io/') - preprint = PreprintFactory(provider=provider) - url = web_url_for('resolve_guid', _guid=True, guid=preprint._id) - res = self.app.get(url) - mock_use_ember_app.assert_called_with() diff --git a/tests/test_preprints.py b/tests/test_preprints.py index da68e579df0..1c5f795de6e 100644 --- a/tests/test_preprints.py +++ b/tests/test_preprints.py @@ -2732,17 +2732,3 @@ def test_date_created_first_version_with_rejected_v1(self, creator, moderator): assert v2.date_created_first_version != v2_created assert v1.date_created_first_version == v1_created - - -class TestEmberRedirect(OsfTestCase): - - def test_ember_redirect_to_versioned_guid(self): - pp = PreprintFactory(filename='test.pdf', finish=True) - res = self.app.get(f'preprints/provider/{pp.get_guid()._id}/') - guid_with_version = pp._id - assert res.status_code == 302 - assert res.location.endswith(f'{guid_with_version}') - guid_with_no_version = guid_with_version.split('_')[0] - location_with_no_guid = res.location.replace(guid_with_version, '') - # check if location has not wrong format https://osf.io/preprints/socarxiv/3rhyz/3rhyz_v1 - assert location_with_no_guid == location_with_no_guid.replace(guid_with_no_version, '') diff --git a/tests/test_project_contributor_views.py b/tests/test_project_contributor_views.py index 0dc4b95d9ff..3c61f273f65 100644 --- a/tests/test_project_contributor_views.py +++ b/tests/test_project_contributor_views.py @@ -428,7 +428,7 @@ def test_multiple_project_remove_contributor(self): self.project.reload() self.project2.reload() assert self.user2._id not in self.project.contributors - assert '/dashboard/' not in res.json + assert '/my_projects/' not in res.json assert self.user2._id not in self.project2.contributors # A log event was added @@ -449,7 +449,7 @@ def test_private_project_remove_self_not_admin(self): ) self.project.reload() assert res.status_code == 200 - assert res.json['redirectUrl'] == '/dashboard/' + assert res.json['redirectUrl'] == '/myprojects/' assert self.user2._id not in self.project.contributors def test_public_project_remove_self_not_admin(self): diff --git a/tests/test_webtests.py b/tests/test_webtests.py index 6f6c719e59c..4b5537d3a29 100644 --- a/tests/test_webtests.py +++ b/tests/test_webtests.py @@ -88,7 +88,7 @@ def test_can_see_profile_url(self): res = self.app.get(self.user.url, follow_redirects=True) assert self.user.url in res.text - # `GET /login/` without parameters is redirected to `/dashboard/` page which has `@must_be_logged_in` decorator + # `GET /login/` without parameters is redirected to `/myprojects/` page which has `@must_be_logged_in` decorator # if user is not logged in, she/he is further redirected to CAS login page def test_is_redirected_to_cas_if_not_logged_in_at_login_page(self): res = self.app.resolve_redirect(self.app.get('/login/')) @@ -96,19 +96,19 @@ def test_is_redirected_to_cas_if_not_logged_in_at_login_page(self): location = res.headers.get('Location') assert 'login?service=' in location - def test_is_redirected_to_dashboard_if_already_logged_in_at_login_page(self): + def test_is_redirected_to_myprojects_if_already_logged_in_at_login_page(self): res = self.app.get('/login/', auth=self.user.auth) assert res.status_code == 302 - assert 'dashboard' in res.headers.get('Location') + assert 'myprojects' in res.headers.get('Location') def test_register_page(self): res = self.app.get('/register/') assert res.status_code == 200 - def test_is_redirected_to_dashboard_if_already_logged_in_at_register_page(self): + def test_is_redirected_to_myprojects_if_already_logged_in_at_register_page(self): res = self.app.get('/register/', auth=self.user.auth) assert res.status_code == 302 - assert 'dashboard' in res.headers.get('Location') + assert 'myprojects' in res.headers.get('Location') def test_sees_projects_in_her_dashboard(self): # the user already has a project diff --git a/website/conferences/views.py b/website/conferences/views.py index cf7dbfd6d3b..c8cd00f4bf3 100644 --- a/website/conferences/views.py +++ b/website/conferences/views.py @@ -15,7 +15,6 @@ from website import settings from website.conferences import utils from website.conferences.message import ConferenceMessage, ConferenceError -from website.ember_osf_web.decorators import ember_flag_is_active from website.mails import CONFERENCE_SUBMITTED, CONFERENCE_INACTIVE, CONFERENCE_FAILED, CONFERENCE_DEPRECATION from website.mails import send_mail from website.util import web_url_for @@ -282,7 +281,6 @@ def serialize_conference(conf): 'talk': conf.talk, } -@ember_flag_is_active(features.EMBER_MEETING_DETAIL) def conference_results(meeting): """Return the data for the grid view for a conference. :param str meeting: Endpoint name for a conference. @@ -313,7 +311,6 @@ def conference_submissions(**kwargs): """ return {'success': True} -@ember_flag_is_active(features.EMBER_MEETINGS) def conference_view(**kwargs): meetings = [] for conf in Conference.objects.all(): diff --git a/website/ember_osf_web/__init__.py b/website/ember_osf_web/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/website/ember_osf_web/decorators.py b/website/ember_osf_web/decorators.py deleted file mode 100644 index 6b939312ee2..00000000000 --- a/website/ember_osf_web/decorators.py +++ /dev/null @@ -1,22 +0,0 @@ -import functools - -from flask import request - -from api.waffle.utils import flag_is_active -from website.ember_osf_web.views import use_ember_app - - -def ember_flag_is_active(flag_name): - """ - Decorator for checking whether ember flag is active. If so, proxy to ember - app; otherwise, load old view. - """ - def decorator(func): - @functools.wraps(func) - def wrapped(*args, **kwargs): - if flag_is_active(request, flag_name): - return use_ember_app() - else: - return func(*args, **kwargs) - return wrapped - return decorator diff --git a/website/ember_osf_web/views.py b/website/ember_osf_web/views.py deleted file mode 100644 index 84f23ad8327..00000000000 --- a/website/ember_osf_web/views.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -import json -from website import settings -from framework.status import pop_status_messages - -from website.settings import EXTERNAL_EMBER_APPS - -ember_osf_web_dir = os.path.abspath(os.path.join(os.getcwd(), EXTERNAL_EMBER_APPS['ember_osf_web']['path'])) - -routes = [ - '/institutions/', -] - -def use_ember_app(**kwargs): - from website.views import stream_emberapp - resp = stream_emberapp(EXTERNAL_EMBER_APPS['ember_osf_web']['server'], ember_osf_web_dir) - messages = pop_status_messages() - if messages: - try: - status = [{'id': stat[5] if stat[5] else stat[0], 'class': stat[2], 'jumbo': stat[1], 'dismiss': stat[3], 'extra': stat[6]} for stat in messages] - resp.set_cookie(settings.COOKIE_NAME + '_status', json.dumps(status)) - except IndexError: - # Ignoring the error as it will only occur when statuses were created prior to merging the changes that add - # extra and id, (patch to prevent breaking the app meanwhile) - pass - return resp diff --git a/website/institutions/__init__.py b/website/institutions/__init__.py deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/website/institutions/views.py b/website/institutions/views.py deleted file mode 100644 index 9477fa8c910..00000000000 --- a/website/institutions/views.py +++ /dev/null @@ -1,7 +0,0 @@ -from website.ember_osf_web.views import use_ember_app - -def view_institution(inst_id, **kwargs): - return use_ember_app() - -def view_institution_dashboard(inst_id, **kwargs): - return use_ember_app() diff --git a/website/preprints/views.py b/website/preprints/views.py index e27da1e7f1f..d42a19b48ae 100644 --- a/website/preprints/views.py +++ b/website/preprints/views.py @@ -1,8 +1,5 @@ from framework.flask import redirect # VOL-aware redirect -def preprint_landing_page(**kwargs): - return {} - def preprint_redirect(**kwargs): return redirect('/preprints/') diff --git a/website/profile/views.py b/website/profile/views.py index 8e66e9341e0..f2cb984e512 100644 --- a/website/profile/views.py +++ b/website/profile/views.py @@ -25,7 +25,6 @@ from framework.status import push_status_message from framework.utils import throttle_period_expired -from osf import features from osf.models import ApiOAuth2Application, ApiOAuth2PersonalToken, OSFUser from osf.exceptions import BlockedEmailError, OSFError from osf.utils.requests import string_type_request_headers @@ -33,7 +32,6 @@ from website import mailchimp_utils from website import settings from website import language -from website.ember_osf_web.decorators import ember_flag_is_active from website.oauth.utils import get_available_scopes from website.profile import utils as profile_utils from website.util import api_v2_url, web_url_for, paths @@ -255,7 +253,6 @@ def profile_view_id_json(uid, auth): return _profile_view(user, is_profile) @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_PROFILE) def profile_view(auth): # Embed node data, so profile node lists can be rendered return _profile_view(auth.user, True, include_node_counts=True) @@ -270,7 +267,6 @@ def profile_view_id(uid, auth): @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS) def user_profile(auth, **kwargs): user = auth.user return { @@ -280,7 +276,6 @@ def user_profile(auth, **kwargs): @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS_ACCOUNTS) def user_account(auth, **kwargs): user = auth.user user_addons = addon_utils.get_addons_by_config_type('user', user) @@ -299,7 +294,6 @@ def user_account(auth, **kwargs): @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS_ACCOUNTS) def user_account_password(auth, **kwargs): user = auth.user old_password = request.form.get('old_password', None) @@ -338,7 +332,6 @@ def user_account_password(auth, **kwargs): @must_be_logged_in -@ember_flag_is_active(features.ENABLE_GV) def user_addons(auth, **kwargs): user = auth.user @@ -356,7 +349,6 @@ def user_addons(auth, **kwargs): return ret @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS_NOTIFICATIONS) def user_notifications(auth, **kwargs): """Get subscribe data from user""" return { @@ -364,7 +356,6 @@ def user_notifications(auth, **kwargs): } @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS_APPS) def oauth_application_list(auth, **kwargs): """Return app creation page with list of known apps. API is responsible for tying list to current user.""" app_list_url = api_v2_url('applications/') @@ -373,7 +364,6 @@ def oauth_application_list(auth, **kwargs): } @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS_APPS) def oauth_application_register(auth, **kwargs): """Register an API application: blank form view""" app_list_url = api_v2_url('applications/') # POST request to this url @@ -381,7 +371,6 @@ def oauth_application_register(auth, **kwargs): 'app_detail_url': ''} @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS_APPS) def oauth_application_detail(auth, **kwargs): """Show detail for a single OAuth application""" client_id = kwargs.get('client_id') @@ -403,7 +392,6 @@ def oauth_application_detail(auth, **kwargs): 'app_detail_url': app_detail_url} @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS_TOKENS) def personal_access_token_list(auth, **kwargs): """Return token creation page with list of known tokens. API is responsible for tying list to current user.""" token_list_url = api_v2_url('tokens/') @@ -412,7 +400,6 @@ def personal_access_token_list(auth, **kwargs): } @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS_TOKENS) def personal_access_token_register(auth, **kwargs): """Register a personal access token: blank form view""" token_list_url = api_v2_url('tokens/') # POST request to this url @@ -421,7 +408,6 @@ def personal_access_token_register(auth, **kwargs): 'scope_options': get_available_scopes()} @must_be_logged_in -@ember_flag_is_active(features.EMBER_USER_SETTINGS_TOKENS) def personal_access_token_detail(auth, **kwargs): """Show detail for a single personal access token""" _id = kwargs.get('_id') diff --git a/website/project/views/contributor.py b/website/project/views/contributor.py index 5001c388d26..f871a9d1f4b 100644 --- a/website/project/views/contributor.py +++ b/website/project/views/contributor.py @@ -299,7 +299,7 @@ def project_manage_contributors(auth, node, **kwargs): raise HTTPError(http_status.HTTP_409_CONFLICT, data={'message_long': error.args[0]}) # If user has removed herself from project, alert; redirect to - # node summary if node is public, else to user's dashboard page + # node summary if node is public, else to user's my_projects page if not node.is_contributor_or_group_member(auth.user): status.push_status_message( 'You have removed yourself as a contributor from this project', @@ -308,7 +308,7 @@ def project_manage_contributors(auth, node, **kwargs): ) if node.is_public: return {'redirectUrl': node.url} - return {'redirectUrl': web_url_for('dashboard')} + return {'redirectUrl': web_url_for('my_projects')} # Else if user has revoked her admin permissions, alert and stay on # current page if not node.has_permission(auth.user, ADMIN): @@ -363,7 +363,7 @@ def project_remove_contributor(auth, **kwargs): 'message_long': 'Could not remove contributor.'}) # On parent node, if user has removed herself from project, alert; redirect to - # node summary if node is public, else to user's dashboard page + # node summary if node is public, else to user's my_projects page if not node.is_contributor_or_group_member(auth.user) and node_id == parent_id: status.push_status_message( 'You have removed yourself as a contributor from this project', @@ -374,7 +374,7 @@ def project_remove_contributor(auth, **kwargs): if node.is_public: redirect_url = {'redirectUrl': node.url} else: - redirect_url = {'redirectUrl': web_url_for('dashboard')} + redirect_url = {'redirectUrl': web_url_for('my_projects')} if node.is_public: node.update_search() diff --git a/website/project/views/drafts.py b/website/project/views/drafts.py index e4ee762c992..a140dee9cb6 100644 --- a/website/project/views/drafts.py +++ b/website/project/views/drafts.py @@ -13,7 +13,6 @@ from framework.database import autoload from framework.exceptions import HTTPError -from osf import features from osf.utils.sanitize import strip_html from osf.utils.permissions import ADMIN from osf.utils.functional import rapply @@ -25,7 +24,6 @@ must_have_permission, ) from website import settings -from website.ember_osf_web.decorators import ember_flag_is_active from website.project import utils from website.project.metadata.schemas import METASCHEMA_ORDERING @@ -153,7 +151,6 @@ def get_draft_registrations(auth, node, *args, **kwargs): @must_have_permission(ADMIN) @must_be_valid_project @must_be_contributor_and_not_group_member -@ember_flag_is_active(features.EMBER_CREATE_DRAFT_REGISTRATION) def new_draft_registration(auth, node, *args, **kwargs): """Create a new draft registration for the node @@ -192,7 +189,6 @@ def new_draft_registration(auth, node, *args, **kwargs): @must_have_permission(ADMIN) @must_be_contributor_and_not_group_member -@ember_flag_is_active(features.EMBER_EDIT_DRAFT_REGISTRATION) @must_be_branched_from_node def edit_draft_registration_page(auth, node, draft, **kwargs): """Draft registration editor diff --git a/website/project/views/file.py b/website/project/views/file.py index 780b26a740c..393782d47ef 100644 --- a/website/project/views/file.py +++ b/website/project/views/file.py @@ -4,13 +4,11 @@ from flask import request from osf import features -from osf.models import Node, Registration from api.waffle.utils import flag_is_active from website.util import rubeus from website.project.decorators import must_be_contributor_or_public, must_not_be_retracted_registration from website.project.views.node import _view_project -from website.ember_osf_web.views import use_ember_app @must_not_be_retracted_registration @@ -19,11 +17,6 @@ def collect_file_trees(auth, node, **kwargs): """Collect file trees for all add-ons implementing HGrid views, then format data as appropriate. """ - if isinstance(node, Node) and flag_is_active(request, features.EMBER_PROJECT_FILES): - return use_ember_app() - - if isinstance(node, Registration) and flag_is_active(request, features.EMBER_REGISTRATION_FILES): - return use_ember_app() serialized = _view_project(node, auth, primary=True) # Add addon static assets diff --git a/website/project/views/node.py b/website/project/views/node.py index c07a1377086..94e4a63fe47 100644 --- a/website/project/views/node.py +++ b/website/project/views/node.py @@ -18,7 +18,6 @@ from framework.auth.decorators import must_be_logged_in, collect_auth from osf.external.gravy_valet.request_helpers import get_gv_citation_url_list_for_project from osf.external.gravy_valet.translations import EphemeralAddonConfig -from website.ember_osf_web.decorators import ember_flag_is_active from api.waffle.utils import flag_is_active, storage_i18n_flag_active, storage_usage_flag_active from framework.exceptions import HTTPError from osf.models.nodelog import NodeLog @@ -31,7 +30,6 @@ from website import language from website.util import rubeus -from website.ember_osf_web.views import use_ember_app from osf.exceptions import NodeStateError from website.project import new_node, new_private_link from website.project.decorators import ( @@ -269,7 +267,6 @@ def project_before_template(auth, node, **kwargs): def node_registrations(auth, node, **kwargs): if request.path.startswith('/project/'): return redirect(f'/{node._id}/registrations/') - return use_ember_app() @must_be_valid_project @@ -278,18 +275,13 @@ def node_registrations(auth, node, **kwargs): def node_forks(auth, node, **kwargs): if request.path.startswith('/project/'): return redirect('/' + node._id + '/forks/') - return use_ember_app() @must_be_valid_project @must_not_be_retracted_registration @must_be_logged_in @must_have_permission(READ) -@ember_flag_is_active(features.EMBER_PROJECT_SETTINGS) def node_setting(auth, node, **kwargs): - if node.is_registration and flag_is_active(request, features.EMBER_REGISTRIES_DETAIL_PAGE): - # Registration settings page obviated during redesign - return redirect(node.url) auth.user.update_affiliated_institutions_by_email_domain() auth.user.save() ret = _view_project(node, auth, primary=True) @@ -324,7 +316,6 @@ def node_setting(auth, node, **kwargs): @must_not_be_registration @must_be_logged_in @must_have_permission(WRITE) -@ember_flag_is_active(features.ENABLE_GV) def node_addons(auth, node, **kwargs): ret = _view_project(node, auth, primary=True) @@ -410,7 +401,6 @@ def node_choose_addons(auth, node, **kwargs): @must_be_valid_project @must_not_be_retracted_registration @must_have_permission(READ) -@ember_flag_is_active(features.EMBER_PROJECT_CONTRIBUTORS) def node_contributors(auth, node, **kwargs): ret = _view_project(node, auth, primary=True) ret['contributors'] = utils.serialize_contributors(node.contributors, node) @@ -458,7 +448,6 @@ def make_citation_widget_data(addon_name: str): @process_token_or_pass @must_be_valid_project(retractions_valid=True) @must_be_contributor_or_public -@ember_flag_is_active(features.EMBER_PROJECT_DETAIL) def view_project(auth, node, **kwargs): primary = '/api/v1' not in request.path ret = _view_project(node, auth, @@ -576,7 +565,6 @@ def project_reorder_components(node, **kwargs): def project_statistics(auth, node, **kwargs): if request.path.startswith('/project/'): return redirect('/' + node._id + '/analytics/') - return use_ember_app() ############################################################################### @@ -654,7 +642,7 @@ def component_remove(auth, node, **kwargs): if parent and parent.can_view(auth): redirect_url = node.parent_node.url else: - redirect_url = '/dashboard/' + redirect_url = '/my_projects/' return { 'url': redirect_url, diff --git a/website/project/views/register.py b/website/project/views/register.py index 265fda1edea..6d8fe5a293f 100644 --- a/website/project/views/register.py +++ b/website/project/views/register.py @@ -15,19 +15,16 @@ must_not_be_registration, must_not_be_retracted_registration ) -from osf import features from osf.models import Identifier, RegistrationSchema from website.project.utils import serialize_node from osf.utils.permissions import ADMIN from website import language -from website.ember_osf_web.decorators import ember_flag_is_active from website.project.metadata.schemas import _id_to_name from website import util from website.project.metadata.utils import serialize_meta_schema from website.project.model import has_anonymous_link from .node import _view_project -from api.waffle.utils import flag_is_active @must_be_valid_project @must_not_be_retracted_registration @@ -117,11 +114,7 @@ def node_registration_retraction_post(auth, node, **kwargs): @must_be_valid_project @must_not_be_retracted_registration @must_be_contributor_or_public -@ember_flag_is_active(features.EMBER_REGISTRATION_FORM_DETAIL) def node_register_template_page(auth, node, metaschema_id, **kwargs): - if flag_is_active(request, features.EMBER_REGISTRIES_DETAIL_PAGE): - # Registration meta page obviated during redesign - return redirect(node.url) if node.is_registration and bool(node.registered_schema): try: meta_schema = RegistrationSchema.objects.get(_id=metaschema_id) diff --git a/website/registries/views.py b/website/registries/views.py index c7307fe626f..d018e971710 100644 --- a/website/registries/views.py +++ b/website/registries/views.py @@ -27,8 +27,3 @@ def draft_registrations(auth, **kwargs): for draft in drafts ], } - - -def registries_landing_page(**kwargs): - # placeholder for developer who don't have ember app set up. - return {} diff --git a/website/reviews/views.py b/website/reviews/views.py deleted file mode 100644 index bbb97564245..00000000000 --- a/website/reviews/views.py +++ /dev/null @@ -1,2 +0,0 @@ -def reviews_landing_page(**kwargs): - return {} diff --git a/website/routes.py b/website/routes.py index 80b0d8bec92..0a1c9e0541e 100644 --- a/website/routes.py +++ b/website/routes.py @@ -1,7 +1,5 @@ import os from rest_framework import status as http_status -import requests -from urllib.parse import urljoin import json import waffle @@ -9,8 +7,6 @@ from flask import request from flask import send_from_directory -from flask import Response -from flask import stream_with_context from flask import g from django.conf import settings as api_settings from django.utils.encoding import smart_str @@ -30,7 +26,7 @@ from framework.auth.core import _get_current_user from osf import features -from osf.models import Institution, Preprint +from osf.models import Institution from osf.utils import sanitize from osf.utils import permissions from website import util @@ -54,13 +50,9 @@ 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 -from website.institutions import views as institution_views from website.notifications import views as notification_views -from website.ember_osf_web import views as ember_osf_web_views from website.closed_challenges import views as closed_challenges_views from website.identifiers import views as identifier_views -from website.settings import EXTERNAL_EMBER_APPS, EXTERNAL_EMBER_SERVER_TIMEOUT from api.waffle.utils import flag_is_active @@ -237,58 +229,9 @@ def sitemap_file(path): mimetype=mime ) -def ember_app(path=None): - """Serve the contents of the ember application""" - ember_app_folder = None - fp = path or 'index.html' - - ember_app = None - - for k in EXTERNAL_EMBER_APPS.keys(): - if request.path.strip('/').startswith(k): - ember_app = EXTERNAL_EMBER_APPS[k] - if k == 'preprints': - # If a valid guid is provided w/o version, find and redirect to the latest version. This only applies - # to route preprints//: e.g. /preprints/osf/abcde -> /preprints/osf/abcde_v3 - if path: - path_values = path.split('/') - guid_str = path_values[1] if len(path_values) > 1 else None - if guid_str: - preprint = Preprint.load(guid_str) - if preprint and preprint._id != guid_str: - return redirect(f"{settings.DOMAIN}preprints/{path_values[0]}/{preprint._id}", code=302) - # For all other cases, let ember app handle it - ember_app = EXTERNAL_EMBER_APPS.get('ember_osf_web', False) or ember_app - break - - if not ember_app: - raise HTTPError(http_status.HTTP_404_NOT_FOUND) - - if settings.PROXY_EMBER_APPS: - path = request.path[len(ember_app['path']):] - url = urljoin(ember_app['server'], path) - resp = requests.get(url, stream=True, timeout=EXTERNAL_EMBER_SERVER_TIMEOUT, headers={'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'}) - excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] - headers = [(name, value) for (name, value) in resp.raw.headers.items() if name.lower() not in excluded_headers] - return Response(resp.content, resp.status_code, headers) - - ember_app_folder = os.path.abspath(os.path.join(os.getcwd(), ember_app['path'])) - - if not ember_app_folder: - raise HTTPError(http_status.HTTP_404_NOT_FOUND) - - if not os.path.abspath(os.path.join(ember_app_folder, fp)).startswith(ember_app_folder): - # Prevent accessing files outside of the ember build dir - raise HTTPError(http_status.HTTP_404_NOT_FOUND) - - if not os.path.isfile(os.path.join(ember_app_folder, fp)): - fp = 'index.html' - - return send_from_directory(ember_app_folder, fp) - def goodbye(): # Redirect to dashboard if logged in - redirect_url = util.web_url_for('index') + redirect_url = util.web_url_for('auth_login') if _get_current_user(): return redirect(redirect_url) else: @@ -348,70 +291,17 @@ def make_url_map(app): Rule('/sitemaps/', 'get', sitemap_file, json_renderer), ]) - # Ember Applications - if settings.USE_EXTERNAL_EMBER: - # Routes that serve up the Ember application. Hide behind feature flag. - for prefix in EXTERNAL_EMBER_APPS.keys(): - process_rules(app, [ - Rule( - [ - '///download', - '///download/', - ], - ['get', 'post', 'put', 'patch', 'delete'], - website_views.resolve_guid_download, - notemplate, - endpoint_suffix='__' + prefix - ), - ], prefix='/' + prefix) - - process_rules(app, [ - Rule( - [ - '/', - '/', - ], - 'get', - ember_app, - json_renderer, - endpoint_suffix='__' + prefix - ), - ], prefix='/' + prefix) - - if EXTERNAL_EMBER_APPS.get('ember_osf_web'): - process_rules(app, [ - Rule( - ember_osf_web_views.routes, - 'get', - ember_osf_web_views.use_ember_app, - notemplate - ) - ]) - if 'routes' in EXTERNAL_EMBER_APPS['ember_osf_web']: - for route in EXTERNAL_EMBER_APPS['ember_osf_web']['routes']: - process_rules(app, [ - Rule( - [ - '/', - '/', - ], - 'get', - ember_osf_web_views.use_ember_app, - notemplate, - endpoint_suffix='__' + route - ) - ], prefix='/' + route) - ### Base ### process_rules(app, [ - + Rule('/', 'get', website_views.index, notemplate), Rule( '/dashboard/', 'get', website_views.dashboard, notemplate ), + Rule( '/metadata//', 'get', @@ -520,26 +410,6 @@ def make_url_map(app): closed_challenges_views.erpc_landing_page, OsfWebRenderer('erpc_landing_page.mako', trust=False) ), - Rule( - '/preprints/', - 'get', - preprint_views.preprint_landing_page, - OsfWebRenderer('public/pages/preprint_landing.mako', trust=False), - ), - - Rule( - '/registries/', - 'get', - registries_views.registries_landing_page, - OsfWebRenderer('public/pages/registries_landing.mako', trust=False), - ), - - Rule( - '/reviews/', - 'get', - reviews_views.reviews_landing_page, - OsfWebRenderer('public/pages/reviews_landing.mako', trust=False), - ), Rule( '/preprint/', @@ -1116,28 +986,9 @@ def make_url_map(app): ], prefix='/api/v1') - # Institution - - process_rules(app, [ - Rule('/institutions//', 'get', institution_views.view_institution, notemplate) - ]) - - process_rules(app, [ - Rule([ - '/institutions//dashboard/', - ], - 'get', - institution_views.view_institution_dashboard, - notemplate) - ]) - - # Project - # Web process_rules(app, [ - Rule('/', 'get', website_views.index, notemplate), - Rule('/goodbye/', 'get', goodbye, notemplate), Rule( @@ -1801,8 +1652,3 @@ def addon_static(addon, filename): @app.route('/assets/') def provider_static(filename): return send_from_directory(directory=provider_static_path, path=filename) - - @app.route('/ember-cli-live-reload.js') - def ember_cli_live_reload(): - req = requests.get(f'{settings.LIVE_RELOAD_DOMAIN}/ember-cli-live-reload.js', stream=True) - return Response(stream_with_context(req.iter_content()), content_type=req.headers['content-type']) diff --git a/website/search/views.py b/website/search/views.py index e774d52532e..828cd0e5661 100644 --- a/website/search/views.py +++ b/website/search/views.py @@ -12,11 +12,9 @@ from framework import sentry from framework.utils import sanitize_html from website import language -from osf import features from osf.models import OSFUser, AbstractNode from website import settings from website.project.views.contributor import get_node_contributors_abbrev -from website.ember_osf_web.decorators import ember_flag_is_active from website.search import exceptions import website.search.search as search from website.search.util import build_query @@ -73,7 +71,6 @@ def search_search(**kwargs): results['time'] = round(time.time() - tick, 2) return results -@ember_flag_is_active(features.EMBER_SEARCH_PAGE) def search_view(): return {'shareUrl': settings.SHARE_URL}, diff --git a/website/settings/defaults.py b/website/settings/defaults.py index aaa8173acf9..3d4e16fbf6b 100644 --- a/website/settings/defaults.py +++ b/website/settings/defaults.py @@ -94,12 +94,6 @@ def parent_dir(path): 'prefix': PROTOCOL, 'suffix': '/' } -# External Ember App Local Development -USE_EXTERNAL_EMBER = False -PROXY_EMBER_APPS = False -# http://docs.python-requests.org/en/master/user/advanced/#timeouts -EXTERNAL_EMBER_SERVER_TIMEOUT = 3.05 -EXTERNAL_EMBER_APPS = {} LOG_PATH = os.path.join(APP_PATH, 'logs') TEMPLATES_PATH = os.path.join(BASE_PATH, 'templates') diff --git a/website/settings/local-ci.py b/website/settings/local-ci.py index c63fce5a86a..430c1b719ff 100644 --- a/website/settings/local-ci.py +++ b/website/settings/local-ci.py @@ -26,21 +26,6 @@ 'prefix': 'http://local.', 'suffix': ':4201/' } -USE_EXTERNAL_EMBER = True -EXTERNAL_EMBER_APPS = { - 'ember_osf_web': { - 'server': 'http://localhost:4200', - 'path': os.environ.get('HOME') + 'website/ember_osf_web/' - }, - 'preprints': { - 'server': 'http://localhost:4201', - 'path': os.environ.get('HOME') + '/preprints/' - }, - 'registries': { - 'server': 'http://localhost:4202/', - 'path': os.environ.get('HOME') + '/registries/' - } -} SEARCH_ENGINE = 'elastic' diff --git a/website/settings/local-dist.py b/website/settings/local-dist.py index 212b9926f7e..551e4b0f424 100644 --- a/website/settings/local-dist.py +++ b/website/settings/local-dist.py @@ -29,29 +29,6 @@ 'prefix': 'http://local.', 'suffix': ':4201/' } -USE_EXTERNAL_EMBER = True -PROXY_EMBER_APPS = True -EMBER_DOMAIN = environ.get('EMBER_DOMAIN', 'localhost') -LIVE_RELOAD_DOMAIN = f'http://{EMBER_DOMAIN}:4200' # Change port for the current app -EXTERNAL_EMBER_APPS = { - 'ember_osf_web': { - 'server': f'http://{EMBER_DOMAIN}:4200/', - 'path': '/ember_osf_web/', - 'routes': [ - 'collections', - 'registries', - 'handbook', - ], - }, - 'preprints': { - 'server': f'http://{EMBER_DOMAIN}:4201/', - 'path': '/preprints/' - }, - 'reviews': { - 'server': f'http://{EMBER_DOMAIN}:4203/', - 'path': '/reviews/' - }, -} SEARCH_ENGINE = 'elastic' ELASTIC_TIMEOUT = 10 diff --git a/website/templates/base.mako b/website/templates/base.mako index 51abe36b06a..d1f08a8ff97 100644 --- a/website/templates/base.mako +++ b/website/templates/base.mako @@ -203,7 +203,7 @@

Start managing your projects on the OSF today.

Free and easy to use, the Open Science Framework supports the entire research lifecycle: planning, execution, reporting, archiving, and discovery.

- Create an Account + Create an Account Learn More Hide this message diff --git a/website/templates/public/forgot_password.mako b/website/templates/public/forgot_password.mako index 63d32ffd7f6..73a0f82b09e 100644 --- a/website/templates/public/forgot_password.mako +++ b/website/templates/public/forgot_password.mako @@ -42,7 +42,7 @@

-
Back to OSF
+
Back to OSF
% endif diff --git a/website/templates/public/pages/preprint_landing.mako b/website/templates/public/pages/preprint_landing.mako deleted file mode 100644 index b405eaa38ab..00000000000 --- a/website/templates/public/pages/preprint_landing.mako +++ /dev/null @@ -1,19 +0,0 @@ -<%inherit file="base.mako"/> - -<%def name="title()">Preprints - -<%def name="content()"> -

Preprints service is not activated.

-
    -
  • Set the following in local.py:
  • -
    USE_EXTERNAL_EMBER = True
    -EXTERNAL_EMBER_APPS = {
    -  'preprints': {
    -    'url': '/preprints/',
    -    'server': 'http://localhost:4200',
    -    'path': '/preprints/'
    -  }
    -}
    -
  • Start the preprints container with docker-compose up -d preprints.
  • -
- diff --git a/website/templates/public/pages/registries_landing.mako b/website/templates/public/pages/registries_landing.mako deleted file mode 100644 index ff974f4e270..00000000000 --- a/website/templates/public/pages/registries_landing.mako +++ /dev/null @@ -1,19 +0,0 @@ -<%inherit file="base.mako"/> - -<%def name="title()">Registries - -<%def name="content()"> -

Registries service is not activated.

-
    -
  • Set the following in local.py:
  • -
    USE_EXTERNAL_EMBER = True
    -EXTERNAL_EMBER_APPS = {
    -  'registries': {
    -    'url': '/registries/',
    -    'server': 'http://localhost:4300',
    -    'path': '/registries/'
    -  }
    -}
    -
  • Start the registries container with docker-compose up -d registries.
  • -
- diff --git a/website/templates/public/pages/reviews_landing.mako b/website/templates/public/pages/reviews_landing.mako deleted file mode 100644 index 0a7fa40575e..00000000000 --- a/website/templates/public/pages/reviews_landing.mako +++ /dev/null @@ -1,19 +0,0 @@ -<%inherit file="base.mako"/> - -<%def name="title()">OSF Reviews - -<%def name="content()"> -

Reviews service is not activated.

-
    -
  • Set the following in local.py:
  • -
    USE_EXTERNAL_EMBER = True
    -EXTERNAL_EMBER_APPS = {
    -  'reviews': {
    -    'url': '/reviews/',
    -    'server': 'http://localhost:4400',
    -    'path': '/reviews/'
    -  }
    -}
    -
  • Start the reviews container with docker-compose up -d reviews.
  • -
- diff --git a/website/views.py b/website/views.py index 112e78f8f88..2d8784618d3 100644 --- a/website/views.py +++ b/website/views.py @@ -3,12 +3,10 @@ from rest_framework import status as http_status import logging import math -import os -import requests from urllib.parse import unquote from django.apps import apps -from flask import request, send_from_directory, Response, stream_with_context +from flask import request, Response from framework.auth import Auth from framework.auth.decorators import must_be_logged_in @@ -21,21 +19,18 @@ from addons.osfstorage.models import Region, OsfStorageFile -from osf import features, exceptions -from osf.models import Guid, Preprint, AbstractNode, Node, DraftNode, Registration, BaseFileNode +from osf import exceptions +from osf.models import Guid, Preprint, AbstractNode, Node, DraftNode -from website.settings import EXTERNAL_EMBER_APPS, PROXY_EMBER_APPS, EXTERNAL_EMBER_SERVER_TIMEOUT, DOMAIN -from website.ember_osf_web.decorators import ember_flag_is_active -from website.ember_osf_web.views import use_ember_app +from website.settings import DOMAIN from website.project.decorators import check_contributor_auth from website.project.model import has_anonymous_link from osf.utils import permissions from osf.metadata.tools import pls_gather_metadata_file -from api.waffle.utils import storage_i18n_flag_active, flag_is_active +from api.waffle.utils import storage_i18n_flag_active logger = logging.getLogger(__name__) -ember_osf_web_dir = os.path.abspath(os.path.join(os.getcwd(), EXTERNAL_EMBER_APPS['ember_osf_web']['path'])) def serialize_contributors_for_summary(node, max_count=3): @@ -131,19 +126,13 @@ def serialize_node_summary(node, auth, primary=True, show_path=False): return summary -def index(): - return use_ember_app() def find_bookmark_collection(user): Collection = apps.get_model('osf.Collection') return Collection.objects.get(creator=user, deleted__isnull=True, is_bookmark_collection=True) -@must_be_logged_in -def dashboard(auth): - return use_ember_app() @must_be_logged_in -@ember_flag_is_active(features.EMBER_MY_PROJECTS) def my_projects(auth): user = auth.user @@ -175,6 +164,14 @@ def paginate(items, total, page, size): return paginated_items, pages +def index(): + return redirect('/myprojects/') + + +def dashboard(): + return redirect('/myprojects/') + + def reproducibility(): return redirect('/ezcuj/wiki') @@ -230,13 +227,6 @@ def resolve_guid_download(guid, provider=None): return proxy_url(_build_guid_url(unquote(resource.deep_url))) -def stream_emberapp(server, directory): - if PROXY_EMBER_APPS: - resp = requests.get(server, stream=True, timeout=EXTERNAL_EMBER_SERVER_TIMEOUT) - return Response(stream_with_context(resp.iter_content()), resp.status_code) - return send_from_directory(directory, 'index.html') - - def _build_guid_url(base, suffix=None): url = '/'.join([ each.strip('/') for each in [base, suffix] @@ -298,41 +288,9 @@ def resolve_guid(guid, suffix=None): format_arg = request.args.get('format') if format_arg: return guid_metadata_download(guid, resource, format_arg) - else: - return use_ember_app() - - # Stream to ember app if resource has emberized view - if isinstance(resource, Preprint): - if resource.provider.domain_redirect_enabled: - return redirect(resource.absolute_url, http_status.HTTP_301_MOVED_PERMANENTLY) - return use_ember_app() - - elif isinstance(resource, Registration) and (clean_suffix in ('', 'comments', 'links', 'components', 'resources',)) and flag_is_active(request, features.EMBER_REGISTRIES_DETAIL_PAGE): - return use_ember_app() - - elif isinstance(resource, Registration) and clean_suffix and clean_suffix.startswith('metadata') and flag_is_active(request, features.EMBER_REGISTRIES_DETAIL_PAGE): - return use_ember_app() - - elif isinstance(resource, Registration) and (clean_suffix in ('files', 'files/osfstorage')) and flag_is_active(request, features.EMBER_REGISTRATION_FILES): - return use_ember_app() - - elif isinstance(resource, Registration) and clean_suffix and (clean_suffix.startswith('recent-activity')): - return use_ember_app() - - elif isinstance(resource, Node) and clean_suffix and clean_suffix.startswith('files') and flag_is_active(request, features.EMBER_PROJECT_FILES): - return use_ember_app() - - elif isinstance(resource, Node) and clean_suffix and (clean_suffix.startswith('metadata') or clean_suffix.startswith('components') or clean_suffix.startswith('links')): - return use_ember_app() - - elif isinstance(resource, OsfStorageFile) and isinstance(resource.target, DraftNode): - return use_ember_app() - elif isinstance(resource, BaseFileNode) and resource.is_file and not isinstance(resource.target, Preprint): - if isinstance(resource.target, Registration) and flag_is_active(request, features.EMBER_FILE_REGISTRATION_DETAIL): - return use_ember_app() - if isinstance(resource.target, Node) and flag_is_active(request, features.EMBER_FILE_PROJECT_DETAIL): - return use_ember_app() + if isinstance(resource, Preprint) and resource.provider.domain_redirect_enabled: + return redirect(resource.absolute_url, http_status.HTTP_301_MOVED_PERMANENTLY) # Redirect to legacy endpoint for Nodes, Wikis etc. url = _build_guid_url(unquote(resource.deep_url), suffix)