Skip to content

Commit

Permalink
Feat: Add support for super admin group (#501)
Browse files Browse the repository at this point in the history
Co-authored-by: Anas-hameed <[email protected]>
  • Loading branch information
Anas-hameed and Anas-hmeed authored Feb 22, 2024
1 parent c356f02 commit 43c2d57
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 16 deletions.
13 changes: 5 additions & 8 deletions cms/djangoapps/contentstore/views/course.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 []
Expand Down
4 changes: 3 additions & 1 deletion cms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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'
Expand Down
4 changes: 3 additions & 1 deletion lms/envs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -1853,14 +1853,16 @@ 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,
'panel_user': EDLY_PANEL_USERS_GROUP,
'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.'
Expand Down
15 changes: 12 additions & 3 deletions openedx/features/edly/api/v1/views/user_mutisites.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -31,15 +33,22 @@ class MultisitesViewset(viewsets.ViewSet):
"""
permission_classes = [permissions.IsAuthenticated]
authentication_classes = [BearerAuthentication]
authentication_classes = [BearerAuthentication, SessionAuthentication]


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)
12 changes: 11 additions & 1 deletion openedx/features/edly/cookies.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
63 changes: 61 additions & 2 deletions openedx/features/edly/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__)

Expand Down Expand Up @@ -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

Expand All @@ -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


Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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)

0 comments on commit 43c2d57

Please sign in to comment.