MOBILE-4323 enrol: Check all methods in courseUsesGuestAccessInfo

main
Dani Palou 2023-08-23 09:51:57 +02:00 committed by Pau Ferrer Ocaña
parent 6862f4e73a
commit 77d4f53d2f
6 changed files with 75 additions and 30 deletions

View File

@ -13,7 +13,12 @@
// limitations under the License. // limitations under the License.
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { CoreEnrolAction, CoreEnrolGuestHandler, CoreEnrolInfoIcon } from '@features/enrol/services/enrol-delegate'; import {
CoreEnrolAction,
CoreEnrolCanAccessData,
CoreEnrolGuestHandler,
CoreEnrolInfoIcon,
} from '@features/enrol/services/enrol-delegate';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonEnrolGuest } from './guest'; import { AddonEnrolGuest } from './guest';
import { CorePasswordModalResponse } from '@components/password-modal/password-modal'; import { CorePasswordModalResponse } from '@components/password-modal/password-modal';
@ -66,10 +71,13 @@ export class AddonEnrolGuestHandlerService implements CoreEnrolGuestHandler {
/** /**
* @inheritdoc * @inheritdoc
*/ */
async canAccess(method: CoreEnrolEnrolmentMethod): Promise<boolean> { async canAccess(method: CoreEnrolEnrolmentMethod): Promise<CoreEnrolCanAccessData> {
const info = await AddonEnrolGuest.getGuestEnrolmentInfo(method.id); const info = await AddonEnrolGuest.getGuestEnrolmentInfo(method.id);
return info.status && (!info.passwordrequired || AddonEnrolGuest.isValidateGuestAccessPasswordAvailable()); return {
canAccess: info.status && (!info.passwordrequired || AddonEnrolGuest.isValidateGuestAccessPasswordAvailable()),
requiresUserInput: info.passwordrequired,
};
} }
/** /**

View File

@ -231,7 +231,7 @@ export class CoreCourseSummaryPage implements OnInit, OnDestroy {
if (!this.canAccessCourse) { if (!this.canAccessCourse) {
// The user is not an admin/manager. Check if we can provide guest access to the course. // The user is not an admin/manager. Check if we can provide guest access to the course.
const promises = this.guestEnrolInstances.map(async (method) => { const promises = this.guestEnrolInstances.map(async (method) => {
const canAccess = await CoreEnrolDelegate.canAccess(method); const { canAccess } = await CoreEnrolDelegate.canAccess(method);
if (canAccess) { if (canAccess) {
this.canAccessCourse = true; this.canAccessCourse = true;
} }

View File

@ -74,8 +74,8 @@ import { CoreCourseWithImageAndColor } from '@features/courses/services/courses-
import { CoreCourseSummaryPage } from '../pages/course-summary/course-summary.page'; import { CoreCourseSummaryPage } from '../pages/course-summary/course-summary.page';
import { CoreRemindersPushNotificationData } from '@features/reminders/services/reminders'; import { CoreRemindersPushNotificationData } from '@features/reminders/services/reminders';
import { CoreLocalNotifications } from '@services/local-notifications'; import { CoreLocalNotifications } from '@services/local-notifications';
import { AddonEnrolGuest } from '@addons/enrol/guest/services/guest';
import { CoreEnrol } from '@features/enrol/services/enrol'; import { CoreEnrol } from '@features/enrol/services/enrol';
import { CoreEnrolAction, CoreEnrolDelegate } from '@features/enrol/services/enrol-delegate';
/** /**
* Prefetch info of a module. * Prefetch info of a module.
@ -594,22 +594,26 @@ export class CoreCourseHelperProvider {
} }
/** /**
* Check whether a course is accessed using guest access and if it requires password to enter. * Check whether a course is accessed using guest access and if it requires user input to enter.
* *
* @param courseId Course ID. * @param courseId Course ID.
* @param siteId Site ID. If not defined, current site. * @param siteId Site ID. If not defined, current site.
* @returns Promise resolved with guestAccess and passwordRequired booleans. * @returns Data about guest access info.
*/ */
async courseUsesGuestAccessInfo( async courseUsesGuestAccessInfo(
courseId: number, courseId: number,
siteId?: string, siteId?: string,
): Promise<{guestAccess: boolean; passwordRequired?: boolean}> { ): Promise<CoreCourseGuestAccessInfo> {
const accessData: CoreCourseGuestAccessInfo = {
guestAccess: false,
};
try { try {
try { try {
// Check if user is enrolled. If enrolled, no guest access. // Check if user is enrolled. If enrolled, no guest access.
await CoreCourses.getUserCourse(courseId, false, siteId); await CoreCourses.getUserCourse(courseId, false, siteId);
return { guestAccess: false }; return accessData;
} catch { } catch {
// Ignore errors. // Ignore errors.
} }
@ -618,26 +622,35 @@ export class CoreCourseHelperProvider {
// The user is not enrolled in the course. Use getCourses to see if it's an admin/manager and can see the course. // The user is not enrolled in the course. Use getCourses to see if it's an admin/manager and can see the course.
await CoreCourses.getCourse(courseId, siteId); await CoreCourses.getCourse(courseId, siteId);
return { guestAccess: false }; return accessData;
} catch { } catch {
// Ignore errors. // Ignore errors.
} }
// Check if guest access is enabled. // Check if guest access is enabled.
const enrolmentMethods = await CoreEnrol.getSupportedCourseEnrolmentMethods(courseId, { type: 'guest', siteId }); const enrolmentMethods = await CoreEnrol.getSupportedCourseEnrolmentMethods(courseId, {
action: CoreEnrolAction.GUEST,
siteId,
});
if (!enrolmentMethods) { if (!enrolmentMethods) {
return { guestAccess: false }; return accessData;
} }
const info = await AddonEnrolGuest.getGuestEnrolmentInfo(enrolmentMethods[0].id); const results = await Promise.all(enrolmentMethods.map(method => CoreEnrolDelegate.canAccess(method)));
// Don't allow guest access if it requires a password and it's available. results.forEach(result => {
return { accessData.guestAccess = accessData.guestAccess || result.canAccess;
guestAccess: info.status && (!info.passwordrequired || AddonEnrolGuest.isValidateGuestAccessPasswordAvailable()), if (accessData.requiresUserInput !== false && result.canAccess) {
passwordRequired: info.passwordrequired, accessData.requiresUserInput = result.requiresUserInput ?? accessData.requiresUserInput;
}; }
});
accessData.passwordRequired = accessData.requiresUserInput; // For backwards compatibility.
return accessData;
} catch { } catch {
return { guestAccess: false }; return accessData;
} }
} }
@ -2192,3 +2205,15 @@ export type CoreCourseOpenModuleOptions = {
sectionId?: number; // Section the module belongs to. sectionId?: number; // Section the module belongs to.
modNavOptions?: CoreNavigationOptions; // Navigation options to open the module, including params to pass to the module. modNavOptions?: CoreNavigationOptions; // Navigation options to open the module, including params to pass to the module.
}; };
/**
* Result of courseUsesGuestAccessInfo.
*/
export type CoreCourseGuestAccessInfo = {
guestAccess: boolean; // Whether guest access is enabled for a course.
requiresUserInput?: boolean; // Whether the first guest access enrolment method requires user input.
/**
* @deprecated since 4.3. Use requiresUserInput instead.
*/
passwordRequired?: boolean;
};

View File

@ -132,7 +132,7 @@ export class CoreCoursesCourseLinkHandlerService extends CoreContentLinksHandler
const guestInfo = await CoreCourseHelper.courseUsesGuestAccessInfo(courseId); const guestInfo = await CoreCourseHelper.courseUsesGuestAccessInfo(courseId);
pageParams.isGuest = guestInfo.guestAccess; pageParams.isGuest = guestInfo.guestAccess;
if (hasAccess && !guestInfo.guestAccess && !guestInfo.passwordRequired) { if (hasAccess && !guestInfo.guestAccess && !guestInfo.requiresUserInput) {
// Direct access. // Direct access.
const course = await CoreUtils.ignoreErrors(CoreCourses.getUserCourse(courseId), { id: courseId }); const course = await CoreUtils.ignoreErrors(CoreCourses.getUserCourse(courseId), { id: courseId });

View File

@ -89,9 +89,9 @@ export interface CoreEnrolGuestHandler extends CoreEnrolHandler {
* Check if the user can access to the course. * Check if the user can access to the course.
* *
* @param method Course enrolment method. * @param method Course enrolment method.
* @returns Whether the user can access. * @returns Access info.
*/ */
canAccess(method: CoreEnrolEnrolmentMethod): Promise<boolean>; canAccess(method: CoreEnrolEnrolmentMethod): Promise<CoreEnrolCanAccessData>;
/** /**
* Validates the access to a course * Validates the access to a course
@ -100,7 +100,6 @@ export interface CoreEnrolGuestHandler extends CoreEnrolHandler {
* @returns Whether the user has validated the access to the course. * @returns Whether the user has validated the access to the course.
*/ */
validateAccess(method: CoreEnrolEnrolmentMethod): Promise<boolean>; validateAccess(method: CoreEnrolEnrolmentMethod): Promise<boolean>;
} }
/** /**
@ -112,6 +111,14 @@ export interface CoreEnrolInfoIcon {
className?: string; className?: string;
} }
/**
* Data about course access using a GUEST enrolment method.
*/
export interface CoreEnrolCanAccessData {
canAccess: boolean; // Whether the user can access the course using this enrolment method.
requiresUserInput?: boolean; // Whether the user needs to input some data to access the course using this enrolment method.
}
/** /**
* Delegate to register enrol handlers. * Delegate to register enrol handlers.
*/ */
@ -193,16 +200,16 @@ export class CoreEnrolDelegateService extends CoreDelegate<CoreEnrolHandler> {
* Check if the user can access to the course. * Check if the user can access to the course.
* *
* @param method Course enrolment method. * @param method Course enrolment method.
* @returns Whether the user can access. * @returns Access data.
*/ */
async canAccess(method: CoreEnrolEnrolmentMethod): Promise<boolean> { async canAccess(method: CoreEnrolEnrolmentMethod): Promise<CoreEnrolCanAccessData> {
const canAccess = await this.executeFunctionOnEnabled<boolean>( const canAccess = await this.executeFunctionOnEnabled<CoreEnrolCanAccessData>(
method.type, method.type,
'canAccess', 'canAccess',
[method], [method],
); );
return !!canAccess; return canAccess ?? { canAccess: false };
} }
/** /**

View File

@ -14,7 +14,12 @@
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
import { CoreSitePluginsBaseHandler } from './base-handler'; import { CoreSitePluginsBaseHandler } from './base-handler';
import { CoreEnrolAction, CoreEnrolHandler, CoreEnrolInfoIcon } from '@features/enrol/services/enrol-delegate'; import {
CoreEnrolAction,
CoreEnrolCanAccessData,
CoreEnrolHandler,
CoreEnrolInfoIcon,
} from '@features/enrol/services/enrol-delegate';
import { CoreSitePluginsContent, CoreSitePluginsEnrolHandlerData } from '@features/siteplugins/services/siteplugins'; import { CoreSitePluginsContent, CoreSitePluginsEnrolHandlerData } from '@features/siteplugins/services/siteplugins';
/** /**
@ -61,9 +66,9 @@ export class CoreSitePluginsEnrolHandler extends CoreSitePluginsBaseHandler impl
/** /**
* @inheritdoc * @inheritdoc
*/ */
async canAccess(): Promise<boolean> { async canAccess(): Promise<CoreEnrolCanAccessData> {
// To be overridden. // To be overridden.
return false; return { canAccess: false };
} }
/** /**