From ba26826896aa44e97b7de54e894c229c0e124d6a Mon Sep 17 00:00:00 2001 From: Jannat Patel Date: Thu, 6 Feb 2025 12:14:24 +0530 Subject: [PATCH] feat: configuration to allow guest access --- frontend/src/components/Modals/ChapterModal.vue | 4 ++-- frontend/src/components/Modals/Settings.vue | 7 +++++++ frontend/src/pages/CourseForm.vue | 4 ++-- frontend/src/pages/LessonForm.vue | 4 ++-- frontend/src/router.js | 12 +++++++++++- frontend/src/stores/settings.js | 13 ++++++++++--- lms/lms/api.py | 7 ++++++- lms/lms/doctype/lms_settings/lms_settings.json | 9 ++++++++- lms/patches.txt | 3 ++- lms/patches/v2_0/allow_guest_access.py | 5 +++++ 10 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 lms/patches/v2_0/allow_guest_access.py diff --git a/frontend/src/components/Modals/ChapterModal.vue b/frontend/src/components/Modals/ChapterModal.vue index 2f02a9e99..8a71c6ace 100644 --- a/frontend/src/components/Modals/ChapterModal.vue +++ b/frontend/src/components/Modals/ChapterModal.vue @@ -145,9 +145,9 @@ const addChapter = async (close) => { { onSuccess(data) { cleanChapter() - if (!settingsStore.onboardingDetails.data?.is_onboarded) { + /* if (!settingsStore.onboardingDetails.data?.is_onboarded) { settingsStore.onboardingDetails.reload() - } + } */ outline.value.reload() showToast( __('Success'), diff --git a/frontend/src/components/Modals/Settings.vue b/frontend/src/components/Modals/Settings.vue index 7f49ac6fe..977f54132 100644 --- a/frontend/src/components/Modals/Settings.vue +++ b/frontend/src/components/Modals/Settings.vue @@ -118,6 +118,13 @@ const tabsStructure = computed(() => { 'This will enforce students to go through programs assigned to them in the correct order.', type: 'checkbox', }, + { + label: 'Allow Guest Access', + name: 'allow_guest_access', + description: + 'If enabled, users can access the course and batch lists without logging in.', + type: 'checkbox', + }, { label: 'Send calendar invite for evaluations', name: 'send_calendar_invite_for_evaluations', diff --git a/frontend/src/pages/CourseForm.vue b/frontend/src/pages/CourseForm.vue index 79b58638f..4ea24855c 100644 --- a/frontend/src/pages/CourseForm.vue +++ b/frontend/src/pages/CourseForm.vue @@ -435,9 +435,9 @@ const submitCourse = () => { onSuccess(data) { capture('course_created') showToast('Success', 'Course created successfully', 'check') - if (!settingsStore.onboardingDetails.data?.is_onboarded) { + /* if (!settingsStore.onboardingDetails.data?.is_onboarded) { settingsStore.onboardingDetails.reload() - } + } */ router.push({ name: 'CourseForm', params: { courseName: data.name }, diff --git a/frontend/src/pages/LessonForm.vue b/frontend/src/pages/LessonForm.vue index f3f687fae..2b37e1afc 100644 --- a/frontend/src/pages/LessonForm.vue +++ b/frontend/src/pages/LessonForm.vue @@ -396,9 +396,9 @@ const createNewLesson = () => { onSuccess() { capture('lesson_created') showToast('Success', 'Lesson created successfully', 'check') - if (!settingsStore.onboardingDetails.data?.is_onboarded) { + /* if (!settingsStore.onboardingDetails.data?.is_onboarded) { settingsStore.onboardingDetails.reload() - } + } */ lessonDetails.reload() }, } diff --git a/frontend/src/router.js b/frontend/src/router.js index 8f3a4999f..a6d02f735 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -1,6 +1,7 @@ import { createRouter, createWebHistory } from 'vue-router' import { usersStore } from './stores/user' import { sessionStore } from './stores/session' +import { useSettings } from './stores/settings' let defaultRoute = '/courses' const routes = [ @@ -218,7 +219,8 @@ let router = createRouter({ router.beforeEach(async (to, from, next) => { const { userResource } = usersStore() - let { isLoggedIn } = sessionStore() + const { isLoggedIn } = sessionStore() + const { allowGuestAccess } = useSettings() try { if (isLoggedIn) { @@ -227,6 +229,14 @@ router.beforeEach(async (to, from, next) => { } catch (error) { isLoggedIn = false } + + if (!isLoggedIn) { + await allowGuestAccess.promise + if (!allowGuestAccess.data) { + window.location.href = '/login' + return + } + } return next() }) diff --git a/frontend/src/stores/settings.js b/frontend/src/stores/settings.js index 184010574..10dcb215b 100644 --- a/frontend/src/stores/settings.js +++ b/frontend/src/stores/settings.js @@ -7,6 +7,7 @@ export const useSettings = defineStore('settings', () => { const { isLoggedIn } = sessionStore() const isSettingsOpen = ref(false) const activeTab = ref(null) + const learningPaths = createResource({ url: 'frappe.client.get_single_value', makeParams(values) { @@ -19,16 +20,22 @@ export const useSettings = defineStore('settings', () => { cache: ['learningPaths'], }) - const onboardingDetails = createResource({ + const allowGuestAccess = createResource({ + url: 'lms.lms.api.is_guest_allowed', + auto: true, + cache: ['allowGuestAccess'], + }) + + /* const onboardingDetails = createResource({ url: 'lms.lms.utils.is_onboarding_complete', auto: isLoggedIn ? true : false, cache: ['onboardingDetails'], - }) + }) */ return { isSettingsOpen, activeTab, learningPaths, - onboardingDetails, + allowGuestAccess, } }) diff --git a/lms/lms/api.py b/lms/lms/api.py index 7ad04441e..0421296c1 100644 --- a/lms/lms/api.py +++ b/lms/lms/api.py @@ -409,7 +409,7 @@ def get_certified_participants(filters=None, start=0, page_length=30, search=Non return participants -@frappe.whitelist() +@frappe.whitelist(allow_guest=True) def get_certification_categories(): categories = [] docs = frappe.get_all( @@ -1220,3 +1220,8 @@ def get_notifications(filters): notification.update(from_user_details) return notifications + + +@frappe.whitelist(allow_guest=True) +def is_guest_allowed(): + return frappe.get_cached_value("LMS Settings", None, "allow_guest_access") diff --git a/lms/lms/doctype/lms_settings/lms_settings.json b/lms/lms/doctype/lms_settings/lms_settings.json index 27bba9ff6..86252fa1b 100644 --- a/lms/lms/doctype/lms_settings/lms_settings.json +++ b/lms/lms/doctype/lms_settings/lms_settings.json @@ -10,6 +10,7 @@ "send_calendar_invite_for_evaluations", "is_onboarding_complete", "column_break_zdel", + "allow_guest_access", "enable_learning_paths", "unsplash_access_key", "livecode_url", @@ -351,12 +352,18 @@ "fieldname": "general_tab", "fieldtype": "Tab Break", "label": "General" + }, + { + "default": "1", + "fieldname": "allow_guest_access", + "fieldtype": "Check", + "label": "Allow Guest Access" } ], "index_web_pages_for_search": 1, "issingle": 1, "links": [], - "modified": "2024-11-20 11:55:05.358421", + "modified": "2025-02-06 11:42:29.803207", "modified_by": "Administrator", "module": "LMS", "name": "LMS Settings", diff --git a/lms/patches.txt b/lms/patches.txt index 5ecffe3d4..097ade7d7 100644 --- a/lms/patches.txt +++ b/lms/patches.txt @@ -96,4 +96,5 @@ lms.patches.v2_0.give_discussions_permissions lms.patches.v2_0.delete_web_forms lms.patches.v2_0.update_desk_access_for_lms_roles lms.patches.v2_0.update_quiz_submission_data -lms.patches.v2_0.convert_quiz_duration_to_minutes \ No newline at end of file +lms.patches.v2_0.convert_quiz_duration_to_minutes +lms.patches.v2_0.allow_guest_access #05-02-2025 \ No newline at end of file diff --git a/lms/patches/v2_0/allow_guest_access.py b/lms/patches/v2_0/allow_guest_access.py new file mode 100644 index 000000000..297adffb7 --- /dev/null +++ b/lms/patches/v2_0/allow_guest_access.py @@ -0,0 +1,5 @@ +import frappe + + +def execute(): + frappe.db.set_single_value("LMS Settings", "allow_guest_access", 1)