Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 2 additions & 7 deletions openedx/core/djangoapps/appsembler/api/sites.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
Organization,
OrganizationCourse,
)
from tahoe_sites.api import get_site_by_organization

from openedx.core.djangoapps.content.course_overviews.models import CourseOverview

Expand Down Expand Up @@ -66,13 +67,7 @@ def get_site_for_course(course_id):
# Keep until this assumption analyzed
msg = 'Multiple orgs found for course: {}'
assert org_courses.count() == 1, msg.format(course_id)
first_org = org_courses.first().organization
if hasattr(first_org, 'sites'):
msg = 'Must have one and only one site. Org is "{}"'
assert first_org.sites.count() == 1, msg.format(first_org.name)
site = first_org.sites.first()
else:
site = None
site = get_site_by_organization(organization=org_courses.get().organization)
else:
# We don't want to make assumptions of who our consumers are
# TODO: handle no organizations found for the course
Expand Down
11 changes: 7 additions & 4 deletions openedx/core/djangoapps/appsembler/settings/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from os import path

from tahoe_sites.api import get_tahoe_sites_auth_backends


def get_tahoe_theme_static_dirs(settings):
"""
Expand Down Expand Up @@ -74,9 +76,10 @@ def get_tahoe_multitenant_auth_backends(settings):
upstream_backend_index = authentication_backends.index(upstream_user_model_backend)

# Use multi-tenant Tahoe backends instead of the upstream EdxRateLimitedAllowAllUsersModelBackend backend.
authentication_backends = settings.AUTHENTICATION_BACKENDS[:upstream_backend_index] + [
'organizations.backends.DefaultSiteBackend',
'organizations.backends.OrganizationMemberBackend',
] + settings.AUTHENTICATION_BACKENDS[upstream_backend_index + 1:]
authentication_backends = (
settings.AUTHENTICATION_BACKENDS[:upstream_backend_index] +
get_tahoe_sites_auth_backends() +
settings.AUTHENTICATION_BACKENDS[upstream_backend_index + 1:]
)

return authentication_backends
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def test_tahoe_backends(self):
"""
Ensure get_tahoe_multitenant_auth_backends adds Tahoe backends to AUTHENTICATION_BACKENDS.
"""
assert 'organizations.backends.DefaultSiteBackend' in settings.AUTHENTICATION_BACKENDS
assert 'organizations.backends.OrganizationMemberBackend' in settings.AUTHENTICATION_BACKENDS
assert 'tahoe_sites.backends.DefaultSiteBackend' in settings.AUTHENTICATION_BACKENDS
assert 'tahoe_sites.backends.OrganizationMemberBackend' in settings.AUTHENTICATION_BACKENDS

def test_instructors_has_access(self):
"""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def _handle_with_atmoic(self, *args, **options):
'organization': {
'name': name,
'short_name': name,
'edx_uuid': uuid.uuid4(),
'edx_uuid': uuid.uuid4(), # TODO: RED-2845 Remove this line when AMC is migrated
},
'initial_values': {
'SITE_NAME': site_name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from django.core.management.base import BaseCommand, CommandError
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models import ForeignKey
from tahoe_sites.api import get_organization_by_site
from tahoe_sites.api import get_organization_by_site, get_uuid_by_organization

from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
Expand Down Expand Up @@ -119,7 +119,7 @@ def generate_objects(self, site):
objects = {
'site': self.process_site(site),
'organizations': [
self.process_organization(org) for org in [organization]
self.process_organization(organization),
],
'courses': self.process_courses(organization),
'configurations': self.process_site_configurations(site),
Expand Down Expand Up @@ -412,7 +412,7 @@ def process_organization(self, organization):
'description': organization.description,
'logo': organization.logo.url if organization.logo else '',
'active': organization.active,
'UUID': organization.edx_uuid,
'UUID': get_uuid_by_organization(organization=organization),
'created': organization.created,
'users': self.process_organization_users(organization)
}
Expand Down
3 changes: 2 additions & 1 deletion openedx/core/djangoapps/appsembler/sites/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from rest_framework import serializers
from organizations import api as organizations_api
from organizations.models import Organization
from tahoe_sites.zd_helpers import should_site_use_org_models

from openedx.core.djangoapps.user_authn.views.registration_form import validate_username
from openedx.core.djangoapps.site_configuration.models import SiteConfiguration
Expand Down Expand Up @@ -87,7 +88,7 @@ def custom_domain_status(self, obj):
class OrganizationSerializer(serializers.ModelSerializer):
class Meta:
model = Organization
fields = ('id', 'name', 'short_name', 'edx_uuid')
fields = ('id', 'name', 'short_name') + ('edx_uuid',) if should_site_use_org_models() else ()

@beeline.traced(name="OrganizationSerializer.create")
def create(self, validated_data):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
create_tahoe_site_by_link,
get_organization_for_user,
get_users_of_organization,
get_uuid_by_organization,
)
from tahoe_sites.tests.utils import create_organization_mapping

Expand Down Expand Up @@ -308,15 +309,17 @@ def test_process_site(self):

@patch('openedx.core.djangoapps.appsembler.sites.management.commands.offboard.Command.process_organization_users', return_value=['user1', 'user2'])
def test_process_organization(self, mock_process_organization_users):
site = SiteFactory(domain='test')
organization = OrganizationFactory.create(name='test')
create_tahoe_site_by_link(organization=organization, site=site)
data = self.command.process_organization(organization)
assert data == {
'name': organization.name,
'short_name': organization.short_name,
'description': organization.description,
'logo': '',
'active': organization.active,
'UUID': organization.edx_uuid,
'UUID': get_uuid_by_organization(organization=organization),
'created': organization.created,
'users': ['user1', 'user2']
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
from django.utils import timezone
from mock import Mock

from organizations.tests.factories import OrganizationFactory
from site_config_client.exceptions import SiteConfigurationError
from tahoe_sites.api import create_tahoe_site, get_uuid_by_organization

from lms.djangoapps.courseware.access_utils import in_preview_mode
from openedx.core.djangoapps.appsembler.sites import (
Expand All @@ -29,11 +29,8 @@

@pytest.fixture
def site_with_org():
org = OrganizationFactory.create()
assert org.edx_uuid, 'Should have valid uuid'
site = Site.objects.create(domain='fake-site')
site.organizations.add(org)
return site, org
site_info = create_tahoe_site(domain='fake-site', short_name='FS')
return site_info['site'], site_info['organization']


@pytest.mark.django_db
Expand All @@ -45,7 +42,8 @@ def test_is_enabled_for_site(monkeypatch, site_with_org):

is_enabled = client_helpers.is_enabled_for_site(site)
assert is_enabled, 'Enabled if client is installed'
helper.assert_called_with(org.edx_uuid)
uuid = get_uuid_by_organization(organization=org)
helper.assert_called_with(uuid)


@pytest.mark.django_db
Expand Down Expand Up @@ -75,7 +73,7 @@ def test_get_configuration_adapter(site_with_org):
with patch('crum.get_current_request', return_value=request):
adapter = client_helpers.init_site_configuration_adapter(site)
assert adapter, 'Should return if client package is installed'
assert adapter.site_uuid == org.edx_uuid, 'Should set the correct ID'
assert adapter.site_uuid == get_uuid_by_organization(organization=org), 'Should set the correct ID'
assert adapter.status == 'draft', 'can be set to draft based on current request parameters'


Expand All @@ -85,7 +83,7 @@ def test_get_configuration_adapter(site_with_org):

adapter = client_helpers.init_site_configuration_adapter(site)
assert adapter, 'Should return if client package is installed'
assert adapter.site_uuid == org.edx_uuid, 'Should set the correct ID'
assert adapter.site_uuid == get_uuid_by_organization(organization=org), 'Should set the correct ID'
assert adapter.status == 'live', 'by default should be live status'


Expand Down
36 changes: 1 addition & 35 deletions openedx/core/djangoapps/appsembler/sites/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,12 @@ def test_get_active_sites_ordering(self):
class OrganizationByRequestTestCase(TestCase):
def setUp(self):
super(OrganizationByRequestTestCase, self).setUp()
self.siteFoo = SiteFactory.create(domain='foo.dev', name='foo.dev')
self.siteBar = SiteFactory.create(domain='bar.dev', name='bar.dev')
self.siteBaz = SiteFactory.create(domain='baz.dev', name='baz.dev')
self.organizationA = OrganizationFactory(linked_site=self.siteFoo)
self.organizationB = OrganizationFactory(linked_site=self.siteFoo)
self.organizationC = OrganizationFactory(linked_site=self.siteBar)
self.request = RequestFactory().post('dummy_url')
self.request.session = {}
for patch_req in (
'openedx.core.djangoapps.appsembler.sites.utils.get_current_request',
'openedx.core.djangoapps.theming.helpers.get_current_request'
'openedx.core.djangoapps.theming.helpers.get_current_request',
):
patcher = patch(patch_req)
patched_req = patcher.start()
Expand All @@ -124,40 +119,11 @@ def test_amc_admin_user_no_org_in_request(self):
# TODO: would be good to test
pass

@patch.dict('django.conf.settings.FEATURES', {'TAHOE_ENABLE_MULTI_ORGS_PER_SITE': False})
def test_single_organization_multiorg_feature_off(self):
self.request.site = self.siteBar
current_org = get_current_organization()
self.assertEqual(current_org, self.organizationC)

@patch.dict('django.conf.settings.FEATURES', {'TAHOE_ENABLE_MULTI_ORGS_PER_SITE': False})
def test_multiple_organization_multiorg_feature_off(self):
self.request.site = self.siteFoo
# fail raising exception if more than one org found for site when feature not enabled
with self.assertRaises(MultipleObjectsReturned):
get_current_organization()

@patch.dict('django.conf.settings.FEATURES', {'TAHOE_ENABLE_MULTI_ORGS_PER_SITE': True})
def test_multiple_organizations_multiorg_feature_on(self):
self.request.site = self.siteFoo
# return one org from Site's org relations
current_org = get_current_organization()
self.assertIn(current_org, (self.organizationA, self.organizationB))

def test_no_org_for_site(self):
self.request.site = self.siteBaz
with self.assertRaises(Organization.DoesNotExist):
get_current_organization()

@patch.dict('django.conf.settings.FEATURES', {
'TAHOE_ENABLE_MULTI_ORGS_PER_SITE': True,
Comment thread
OmarIthawi marked this conversation as resolved.
Outdated
'APPSEMBLER_MULTI_TENANT_EMAILS': True
})
def test_raises_if_multiorg_feature_and_multitenant_email_feature_on(self):
self.request.site = self.siteFoo
with self.assertRaises(ImproperlyConfigured):
get_current_organization()


class LMSLinkByCourseOrgTestCase(TestCase):
"""
Expand Down
33 changes: 8 additions & 25 deletions openedx/core/djangoapps/appsembler/sites/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from django.conf import settings
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core.exceptions import ImproperlyConfigured

from oauth2_provider.models import AccessToken, RefreshToken, Application
from oauth2_provider.generators import generate_client_id
Expand All @@ -38,7 +37,10 @@
from tahoe_sites.api import (
add_user_to_organization,
create_tahoe_site_by_link,
get_organization_by_site,
get_organization_for_user,
get_organizations_from_uuids,
get_sites_from_organizations,
update_admin_role_in_organization,
)

Expand Down Expand Up @@ -93,10 +95,7 @@ def get_active_organizations():
"""
active_tiers_uuids = get_active_organizations_uuids()

# Now back to the LMS MySQL database
return Organization.objects.filter(
edx_uuid__in=[str(edx_uuid) for edx_uuid in active_tiers_uuids],
Comment thread
shadinaif marked this conversation as resolved.
Outdated
)
return get_organizations_from_uuids(uuids=active_tiers_uuids)


def get_active_sites(order_by='domain'):
Expand All @@ -108,9 +107,7 @@ def get_active_sites(order_by='domain'):

TODO: This helper should live in a future Tahoe Sites package.
"""
return Site.objects.filter(
organizations__in=get_active_organizations()
).order_by(order_by)
return get_sites_from_organizations(organizations=get_active_organizations()).order_by(order_by)


@beeline.traced(name="get_amc_oauth_app")
Expand Down Expand Up @@ -308,22 +305,8 @@ def _get_current_organization(failure_return_none=False):
)
else:
try:
if settings.FEATURES.get('TAHOE_ENABLE_MULTI_ORGS_PER_SITE', False):
Comment thread
OmarIthawi marked this conversation as resolved.
Outdated
if settings.FEATURES.get('APPSEMBLER_MULTI_TENANT_EMAILS', False):
raise ImproperlyConfigured(
'TAHOE_ENABLE_MULTI_ORGS_PER_SITE and '
'APPSEMBLER_MULTI_TENANT_EMAILS are incompatible as '
'we are not able to determine the exact Org when more than one '
'is associated with a Site.')
current_org = current_site.organizations.first()
if not current_org:
raise Organization.DoesNotExist(
'TAHOE_ENABLE_MULTI_ORGS_PER_SITE: Could not find current '
'organization for site `{}`'.format(repr(current_site))
)
else:
current_org = current_site.organizations.get()
except (Organization.DoesNotExist, ImproperlyConfigured):
current_org = get_organization_by_site(site=current_site)
except Organization.DoesNotExist:
if not failure_return_none:
raise # Re-raise the exception
else:
Expand Down Expand Up @@ -481,7 +464,7 @@ def bootstrap_site(site, org_data=None, username=None):
organization_data = org_api.add_organization({
'name': organization_slug,
'short_name': organization_slug,
Comment thread
shadinaif marked this conversation as resolved.
Outdated
'edx_uuid': org_data.get('edx_uuid')
'edx_uuid': org_data.get('edx_uuid') # TODO: RED-2845 Remove this line when AMC is migrated
})
organization = org_models.Organization.objects.get(id=organization_data.get('id'))
create_tahoe_site_by_link(organization=organization, site=site)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
A module for deprecated AMC tier utilities.

TODO: Remove this module once AMC is shut down.
TODO: Remove this module once AMC is shut down. Related to RED-2845 too
"""

import logging
Expand Down