Skip to content

Commit

Permalink
fix: waffle flags in flask context (CenterForOpenScience#10664)
Browse files Browse the repository at this point in the history
* fix: waffle flags in flask context
  • Loading branch information
aaxelb authored and Jon Walz committed Jul 25, 2024
1 parent 49ccf2d commit 164a12e
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 40 deletions.
5 changes: 3 additions & 2 deletions addons/base/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from addons.osfstorage.models import OsfStorageFileNode
from addons.osfstorage.utils import enqueue_update_analytics

from api.waffle.utils import flag_is_active
from framework import sentry
from framework.auth import Auth
from framework.auth import cas
Expand Down Expand Up @@ -869,10 +870,10 @@ 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.
if action != 'download':
if isinstance(target, Node) and waffle.flag_is_active(request, features.EMBER_FILE_PROJECT_DETAIL):
if isinstance(target, Node) and flag_is_active(request, features.EMBER_FILE_PROJECT_DETAIL):
guid = file_node.get_guid(create=True)
return redirect(f'{settings.DOMAIN}{guid._id}/')
if isinstance(target, Registration) and waffle.flag_is_active(request, features.EMBER_FILE_REGISTRATION_DETAIL):
if isinstance(target, Registration) and flag_is_active(request, features.EMBER_FILE_REGISTRATION_DETAIL):
guid = file_node.get_guid(create=True)
return redirect(f'{settings.DOMAIN}{guid._id}/')

Expand Down
4 changes: 2 additions & 2 deletions api/institutions/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import jwe
import jwt
import waffle

from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed, PermissionDenied
Expand All @@ -14,6 +13,7 @@

from api.base.authentication import drf
from api.base import exceptions, settings
from api.waffle.utils import flag_is_active

from framework import sentry
from framework.auth import get_or_create_institutional_user
Expand Down Expand Up @@ -339,7 +339,7 @@ def authenticate(self, request):
user=user,
domain=DOMAIN,
osf_support_email=OSF_SUPPORT_EMAIL,
storage_flag_is_active=waffle.flag_is_active(request, features.STORAGE_I18N),
storage_flag_is_active=flag_is_active(request, features.STORAGE_I18N),
)

# Add the email to the user's account if it is identified by the eppn
Expand Down
19 changes: 11 additions & 8 deletions api/waffle/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from framework.auth.core import _get_current_user
from osf import features
from flask import request
import flask


class MockUser:
Expand All @@ -13,18 +13,21 @@ def flag_is_active(request, flag_name):
"""
This function changes the typical flask request object so it can be used by django-waffle. Other modifications for
django-waffle can be found in the __call__ method of OsfWebRenderer.
:param flask request object:
:return flask request object:
:param request (flask or django):
:param flag name (string):
:return bool:
"""
# Waffle does not enjoy NoneTypes as user values.
request.user = _get_current_user() or MockUser()
request.COOKIES = getattr(request, 'cookies', None)
if isinstance(request, flask.Request):
# Waffle does not enjoy NoneTypes as user values.
request.user = _get_current_user() or MockUser()
request.COOKIES = getattr(request, 'cookies', None)
return waffle.flag_is_active(request, flag_name)


def storage_i18n_flag_active():
return flag_is_active(request, features.STORAGE_I18N)
return flag_is_active(flask.request, features.STORAGE_I18N)


def storage_usage_flag_active():
return flag_is_active(request, features.STORAGE_USAGE)
return flag_is_active(flask.request, features.STORAGE_USAGE)
5 changes: 3 additions & 2 deletions osf/external/messages/celery_publishers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import waffle
from kombu import Exchange

from api.waffle.utils import flag_is_active
from framework.celery_tasks import app as celery_app
from website import settings
from osf import features
Expand Down Expand Up @@ -36,7 +37,7 @@ def publish_merged_user(user):


def _publish_user_status_change(body: dict):
if settings.USE_CELERY and waffle.flag_is_active(get_current_request(), features.ENABLE_GV):
if settings.USE_CELERY and flag_is_active(get_current_request(), features.ENABLE_GV):
with celery_app.producer_pool.acquire() as producer:
producer.publish(
body=body,
Expand Down
7 changes: 3 additions & 4 deletions osf/models/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import markupsafe
import logging

import waffle

from django.apps import apps
from django.contrib.auth.models import Group, AnonymousUser
from django.core.exceptions import ObjectDoesNotExist, ValidationError
Expand All @@ -14,6 +12,7 @@
from guardian.shortcuts import assign_perm, get_perms, remove_perm, get_group_perms

from api.providers.workflows import Workflows, PUBLIC_STATES
from api.waffle.utils import flag_is_active
from framework import status
from framework.auth import Auth
from framework.auth.core import get_user
Expand Down Expand Up @@ -491,7 +490,7 @@ def addons(self):

def get_addons(self):
request, user_id = get_request_and_user_id()
if waffle.flag_is_active(request, features.ENABLE_GV):
if flag_is_active(request, features.ENABLE_GV):
osf_addons = filter(
lambda x: x is not None,
(self.get_addon(addon) for addon in self.OSF_HOSTED_ADDONS)
Expand Down Expand Up @@ -528,7 +527,7 @@ def get_addon(self, name, is_deleted=False):
# Avoid test-breakages by avoiding early access to the request context
if name not in self.OSF_HOSTED_ADDONS:
request, user_id = get_request_and_user_id()
if waffle.flag_is_active(request, features.ENABLE_GV):
if flag_is_active(request, features.ENABLE_GV):
return self._get_addon_from_gv(gv_pk=name, requesting_user_id=user_id)

try:
Expand Down
4 changes: 2 additions & 2 deletions tests/test_ember_osf_web.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_dont_use_ember_app(self, mock_use_ember_app):
assert not mock_use_ember_app.called

@mock.patch('api.waffle.utils._get_current_user')
@mock.patch('website.ember_osf_web.decorators.waffle.flag_is_active')
@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 'waflle.flag_is_active` not ours
Expand All @@ -45,7 +45,7 @@ def test_ember_flag_is_active_authenticated_user(self, mock_use_ember_app, mock_
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.waffle.flag_is_active')
@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 'waflle.flag_is_active` not ours
Expand Down
4 changes: 2 additions & 2 deletions website/ember_osf_web/decorators.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import waffle
import functools

from flask import request

from api.waffle.utils import flag_is_active
from website.ember_osf_web.views import use_ember_app


Expand All @@ -14,7 +14,7 @@ def ember_flag_is_active(flag_name):
def decorator(func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
if waffle.flag_is_active(request, flag_name):
if flag_is_active(request, flag_name):
return use_ember_app()
else:
return func(*args, **kwargs)
Expand Down
4 changes: 2 additions & 2 deletions website/oauth/views.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from rest_framework import status as http_status
import waffle
import requests
from urllib.parse import (
urlencode,
Expand All @@ -9,6 +8,7 @@

from flask import redirect, request

from api.waffle.utils import flag_is_active
from framework.auth.decorators import must_be_logged_in
from framework.exceptions import HTTPError
from osf.models import ExternalAccount
Expand Down Expand Up @@ -48,7 +48,7 @@ def oauth_connect(service_name, auth):

@must_be_logged_in
def oauth_callback(service_name, auth):
if waffle.flag_is_active(request, features.ENABLE_GV):
if flag_is_active(request, features.ENABLE_GV):
_forward_to_addon_service()
return {}

Expand Down
6 changes: 3 additions & 3 deletions website/project/views/file.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
"""
Files views.
"""
import waffle
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
Expand All @@ -19,10 +19,10 @@ 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 waffle.flag_is_active(request, features.EMBER_PROJECT_FILES):
if isinstance(node, Node) and flag_is_active(request, features.EMBER_PROJECT_FILES):
return use_ember_app()

if isinstance(node, Registration) and waffle.flag_is_active(request, features.EMBER_REGISTRATION_FILES):
if isinstance(node, Registration) and flag_is_active(request, features.EMBER_REGISTRATION_FILES):
return use_ember_app()

serialized = _view_project(node, auth, primary=True)
Expand Down
27 changes: 14 additions & 13 deletions website/views.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
from furl import furl
import waffle
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import furl
import itertools
from rest_framework import status as http_status
import logging
import math
import os
import requests
from urllib.parse import unquote
from future.moves.urllib.parse import unquote

from django.apps import apps
from flask import request, send_from_directory, Response, stream_with_context
Expand All @@ -33,7 +34,7 @@
from osf.utils import permissions
from osf.metadata.tools import pls_gather_metadata_file

from api.waffle.utils import storage_i18n_flag_active
from api.waffle.utils import storage_i18n_flag_active, flag_is_active

logger = logging.getLogger(__name__)
ember_osf_web_dir = os.path.abspath(os.path.join(os.getcwd(), EXTERNAL_EMBER_APPS['ember_osf_web']['path']))
Expand Down Expand Up @@ -265,7 +266,7 @@ def _build_guid_url(base, suffix=None):
])
if not isinstance(url, str):
url = url.decode('utf-8')
return f'/{url}/'
return u'/{0}/'.format(url)


def resolve_guid(guid, suffix=None):
Expand Down Expand Up @@ -331,25 +332,25 @@ def resolve_guid(guid, suffix=None):
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 waffle.flag_is_active(request, features.EMBER_REGISTRIES_DETAIL_PAGE):
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 waffle.flag_is_active(request, features.EMBER_REGISTRIES_DETAIL_PAGE):
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 waffle.flag_is_active(request, features.EMBER_REGISTRATION_FILES):
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, Node) and clean_suffix and any(path.startswith(clean_suffix) for path in addon_paths) and waffle.flag_is_active(request, features.EMBER_PROJECT_FILES):
elif isinstance(resource, Node) and clean_suffix and any(path.startswith(clean_suffix) for path in addon_paths) 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'):
return use_ember_app()

elif isinstance(resource, BaseFileNode) and resource.is_file and not isinstance(resource.target, Preprint):
if isinstance(resource.target, Registration) and waffle.flag_is_active(request, features.EMBER_FILE_REGISTRATION_DETAIL):
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 waffle.flag_is_active(request, features.EMBER_FILE_PROJECT_DETAIL):
if isinstance(resource.target, Node) and flag_is_active(request, features.EMBER_FILE_PROJECT_DETAIL):
return use_ember_app()

# Redirect to legacy endpoint for Nodes, Wikis etc.
Expand Down Expand Up @@ -390,15 +391,15 @@ def redirect_to_cos_news(**kwargs):

def redirect_to_registration_workflow(**kwargs):
# Redirect to making new registration
return redirect(furl(DOMAIN).add(path='registries/osf/new').url)
return redirect(furl.furl(DOMAIN).add(path='registries/osf/new').url)


# Return error for legacy SHARE v1 search route
def legacy_share_v1_search(**kwargs):
return HTTPError(
http_status.HTTP_400_BAD_REQUEST,
data=dict(
message_long=f'Please use v2 of the SHARE search API available at {settings.SHARE_URL}api/v2/share/search/creativeworks/_search.'
message_long='Please use v2 of the SHARE search API available at {}api/v2/share/search/creativeworks/_search.'.format(settings.SHARE_URL)
)
)

Expand Down

0 comments on commit 164a12e

Please sign in to comment.