diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index 9862f01925d6..b75184da3545 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -19,6 +19,7 @@ from ccx_keys.locator import CCXLocator from django.conf import settings from django.contrib.auth.decorators import login_required +from django.contrib.sites.shortcuts import get_current_site from django.core.exceptions import PermissionDenied, ValidationError from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseNotFound from django.shortcuts import redirect @@ -55,7 +56,8 @@ from openedx.features.content_type_gating.partitions import CONTENT_TYPE_GATING_SCHEME from openedx.features.course_experience.waffle import ENABLE_COURSE_ABOUT_SIDEBAR_HTML from openedx.features.course_experience.waffle import waffle as course_experience_waffle -from openedx.features.edly.utils import filter_courses_based_on_org, get_edx_org_from_cookie, get_enabled_organizations +from openedx.features.edly.models import EdlySubOrganization +from openedx.features.edly.utils import filter_courses_based_on_org from openedx.features.edly.validators import is_courses_limit_reached_for_plan from common.djangoapps.student import auth from common.djangoapps.student.auth import has_course_author_access, has_studio_read_access, has_studio_write_access @@ -574,14 +576,9 @@ def course_listing(request): optimization_enabled = GlobalStaff().has_user(request.user) and \ WaffleSwitchNamespace(name=WAFFLE_NAMESPACE).is_enabled(u'enable_global_staff_optimization') - org = request.GET.get('org', '') if optimization_enabled else None - - enabled_organizations = get_enabled_organizations(request) - org = enabled_organizations[0].get('short_name', '') if enabled_organizations else None - - edly_user_info_cookie = request.COOKIES.get(settings.EDLY_USER_INFO_COOKIE_NAME, None) - org = get_edx_org_from_cookie(edly_user_info_cookie) + site = get_current_site(request) + org = [EdlySubOrganization.objects.filter(studio_site=site).first().slug] courses_iter, in_process_course_actions = get_courses_accessible_to_user(request, org) user = request.user libraries = _accessible_libraries_iter(request.user, org) if LIBRARIES_ENABLED else [] diff --git a/cms/envs/common.py b/cms/envs/common.py index d0e8152ea229..0f46df8a43d0 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -767,6 +767,7 @@ EDLY_WP_ADMIN_USERS_GROUP = 'WordPress Edly Admin Users' EDLY_WP_SUBSCRIBER_USERS_GROUP = 'WordPress Subscriber Users' EDLY_API_USERS_GROUP = 'Edly API Users' +EDLY_PANEL_SUPER_ADMIN = 'Edly Panel Super Admin' EDLY_USER_ROLES = { @@ -775,7 +776,8 @@ 'insights_admin': EDLY_INSIGHTS_GROUP, 'panel_admin': EDLY_PANEL_ADMIN_USERS_GROUP, 'subscriber': EDLY_WP_SUBSCRIBER_USERS_GROUP, - 'edly_admin': EDLY_WP_ADMIN_USERS_GROUP + 'edly_admin': EDLY_WP_ADMIN_USERS_GROUP, + 'super_admin': EDLY_PANEL_SUPER_ADMIN } ENABLE_EDLY_ORGANIZATIONS_SWITCH = 'enable_edly_organizations' diff --git a/lms/envs/common.py b/lms/envs/common.py index 9bd3f2376a9b..83cf1e4a8bc5 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -1853,6 +1853,7 @@ def _make_locale_paths(settings): # pylint: disable=missing-function-docstring EDLY_WP_ADMIN_USERS_GROUP = 'WordPress Edly Admin Users' EDLY_WP_SUBSCRIBER_USERS_GROUP = 'WordPress Subscriber Users' EDLY_API_USERS_GROUP = 'Edly API Users' +EDLY_PANEL_SUPER_ADMIN = 'Edly Panel Super Admin' EDLY_USER_ROLES = { 'panel_restricted': EDLY_PANEL_RESTRICTED_USERS_GROUP, @@ -1860,7 +1861,8 @@ def _make_locale_paths(settings): # pylint: disable=missing-function-docstring 'insights_admin': EDLY_INSIGHTS_GROUP, 'panel_admin': EDLY_PANEL_ADMIN_USERS_GROUP, 'subscriber': EDLY_WP_SUBSCRIBER_USERS_GROUP, - 'edly_admin': EDLY_WP_ADMIN_USERS_GROUP + 'edly_admin': EDLY_WP_ADMIN_USERS_GROUP, + 'super_admin': EDLY_PANEL_SUPER_ADMIN } STUDIO_DOMAIN_PREFIX = 'studio.' diff --git a/openedx/features/edly/api/v1/views/user_mutisites.py b/openedx/features/edly/api/v1/views/user_mutisites.py index ea647e19c971..4851d1734ae7 100644 --- a/openedx/features/edly/api/v1/views/user_mutisites.py +++ b/openedx/features/edly/api/v1/views/user_mutisites.py @@ -5,10 +5,12 @@ from rest_framework import permissions, viewsets from rest_framework.response import Response +from rest_framework.authentication import SessionAuthentication from openedx.features.edly.api.serializers import MutiSiteAccessSerializer from openedx.core.lib.api.authentication import BearerAuthentication from openedx.features.edly.models import EdlyMultiSiteAccess +from openedx.features.edly.utils import get_edly_sub_org_from_request class MultisitesViewset(viewsets.ViewSet): @@ -31,7 +33,7 @@ class MultisitesViewset(viewsets.ViewSet): """ permission_classes = [permissions.IsAuthenticated] - authentication_classes = [BearerAuthentication] + authentication_classes = [BearerAuthentication, SessionAuthentication] def list(self, request, *args, **kwargs): @@ -39,7 +41,14 @@ def list(self, request, *args, **kwargs): Returns a list of Site linked with the user email """ email = request.GET.get('email', '') - queryset = EdlyMultiSiteAccess.objects.filter(user__email=urllib.parse.unquote(email)) - serializer = MutiSiteAccessSerializer(queryset, many=True) + if email: + queryset = EdlyMultiSiteAccess.objects.filter(user__email=urllib.parse.unquote(email)) + else: + sub_org = get_edly_sub_org_from_request(request) + queryset = EdlyMultiSiteAccess.objects.filter( + user=request.user, + sub_org__edly_organization=sub_org.edly_organization + ) + serializer = MutiSiteAccessSerializer(queryset, many=True) return Response(serializer.data) diff --git a/openedx/features/edly/cookies.py b/openedx/features/edly/cookies.py index a888ba442adc..ae558c6ee355 100644 --- a/openedx/features/edly/cookies.py +++ b/openedx/features/edly/cookies.py @@ -76,15 +76,25 @@ def _get_edly_user_info_cookie_string(request): edly_access_user = user.edly_multisite_user.get(sub_org=edly_sub_organization) user_groups.extend(edly_access_user.groups.all().values_list('name', flat=True)) + sub_org = list( + EdlyMultiSiteAccess.objects.filter( + user=request.user, + sub_org__in=EdlySubOrganization.objects.filter( + edly_organization=edly_sub_organization.edly_organization + ) + ).values_list('sub_org__slug',flat=True) + ) + edly_user_info_cookie_data = { 'edly-org': edly_sub_organization.edly_organization.slug, 'edly-sub-org': edly_sub_organization.slug, - 'edx-orgs': edly_sub_organization.get_edx_organizations, + 'edx-orgs': sub_org, 'is_course_creator': auth.user_has_role( request.user, CourseCreatorRole() ) if getattr(request, 'user', None) else False, 'user_groups': user_groups, + 'sub-orgs': sub_org } return encode_edly_user_info_cookie(edly_user_info_cookie_data) except (EdlySubOrganization.DoesNotExist, EdlyMultiSiteAccess.DoesNotExist): diff --git a/openedx/features/edly/utils.py b/openedx/features/edly/utils.py index 203d0340ea82..6e76ccfaa810 100644 --- a/openedx/features/edly/utils.py +++ b/openedx/features/edly/utils.py @@ -36,6 +36,7 @@ from openedx.features.edly.constants import ESSENTIALS, DEFAULT_COURSE_IMAGE, DEFAULT_COURSE_IMAGE_PATH from openedx.features.edly.context_processor import Colour from openedx.features.edly.models import EdlyMultiSiteAccess, EdlySubOrganization +from common.djangoapps.student.models import UserProfile LOGGER = logging.getLogger(__name__) @@ -67,7 +68,6 @@ def user_has_edly_organization_access(request): Returns: bool: Returns True if User has Edly Organization Access Otherwise False. """ - if request.user.is_superuser or request.user.is_staff: return True @@ -89,6 +89,17 @@ def user_has_edly_organization_access(request): if edly_sub_org.slug == get_edly_sub_org_from_cookie(edly_user_info_cookie): return True + edly_org = edly_sub_org.edly_organization + edly_slug = get_edly_org_from_cookie(edly_user_info_cookie) + edly_access_user = request.user.edly_multisite_user.filter( + Q(sub_org__lms_site=current_site) | + Q(sub_org__studio_site=current_site) | + Q(sub_org__preview_site=current_site) + ) + + if edly_access_user.exists() and edly_org.enable_all_edly_sub_org_login and edly_org.slug == edly_slug: + return True + return False @@ -140,6 +151,24 @@ def get_edly_sub_org_from_cookie(encoded_cookie_data): return decoded_cookie_data['edly-sub-org'] +def get_edly_org_from_cookie(encoded_cookie_data): + """ + Returns edly-org from the edly-user-info cookie. + + Arguments: + encoded_cookie_data (dict): Edly user info cookie JWT encoded string. + + Returns: + string + """ + + if not encoded_cookie_data: + return '' + + decoded_cookie_data = decode_edly_user_info_cookie(encoded_cookie_data) + return decoded_cookie_data['edly-org'] + + def get_edx_org_from_cookie(encoded_cookie_data): """ Returns edx-orgs short name from the edly-user-info cookie. @@ -659,7 +688,7 @@ def add_default_image_to_course_assets(course_key): contentstore().save(content) del_cached_content(content.location) -from common.djangoapps.student.models import UserProfile + def get_username_and_name_by_email(email): """ helper function to return username if exists @@ -673,3 +702,33 @@ def get_username_and_name_by_email(email): if userProfile.exists(): userProfile = userProfile.first() return { "username": user.username, "name": userProfile.name } + + +def create_super_user_multisite_access(request, user, groups_names): + """create an edly multisite access for a given user to all the organization sites""" + edly_sub_org = get_edly_sub_org_from_request(request) + sub_org = EdlySubOrganization.objects.filter(edly_organization=edly_sub_org.edly_organization) + groups = Group.objects.filter(name__in=groups_names) + + for org in sub_org: + edly_access_user, created = EdlyMultiSiteAccess.objects.get_or_create( + user=user, + sub_org=org + ) + + if created: + for new_group in groups: + edly_access_user.groups.add(new_group) + + +def create_user_access_role(request ,user ,groups_names): + """create the user access role based on panel role""" + panel_role = request.data.get('panel_role', None) + if settings.EDLY_USER_ROLES.get(panel_role, None)==settings.EDLY_PANEL_SUPER_ADMIN: + groups_names.append(settings.EDLY_PANEL_ADMIN_USERS_GROUP) + create_super_user_multisite_access(request, user, groups_names) + else: + edly_access_user = create_edly_access_role(request, user) + groups = Group.objects.filter(name__in=groups_names) + for new_group in groups: + edly_access_user.groups.add(new_group)