stable
Clone or download
Part of story #35094 have "calendar" events attached to tracker email notification A regular user may not have access to date fields and calendar event cannot be builded. So the check perm need to be bypassed in this case. We thought about different solutions to achieve this: A. New methods in TimeframeChangesetFieldsValueRetriever which do not check permissions `- buildDatePeriodWithoutWeekendForChangesetWitoutCheckingPermissions($changeset, $logger) |- TimeframeChangesetFieldsValueRetriever::getTimestampWitoutCheckingPermissions($start_date_field, $changeset) `- TimeframeChangesetFieldsValueRetriever::getDurationFieldValueWitoutCheckingPermissions($duration_field, $changeset) B. Encapsulate user in Tracker_UserWithReadAllPermissions and check with instanceof ```php if (! $user instanceof \Tracker_UserWithReadAllPermission && ! $date_field->userCanRead($user)) { throw new TimeframeFieldNotFoundException(); } ``` C. Create a system user like Tracker_Workflow_WorkflowUser who have all the read permissions D. Add an argument to methods in TimeframeChangesetFieldsValueRetriever based on Option<> -> we check only if ::isValue ```php final class BypassPermissionCheckTimeframeValueRetriever { private function __construct() { } public static function check(): Option { return Option::fromValue(new self()); } public static function skip(): Option { return Option::nothing(self::class); } } ``` E. Same as D, but with a boolean instead of `Option` F. Add an interface with one function isAllowed and implement it in 2 classes CheckPerms and BypassPerms. Then pass an instance of these classes to TimeframeChangesetFieldsValueRetriever who call the method. ```php interface CheckUserIsAllowedToSeeDateTimePeriod { public function isAllowed( \Tracker_FormElement_Field $field, \PFUser $user ): bool; } final class ByPassPerms implements CheckUserIsAllowedToSeeDateTimePeriod { public function isAllowed( \Tracker_FormElement_Field $field, \PFUser $user ): bool { return true; } } final class CheckPerms implements CheckUserIsAllowedToSeeDateTimePeriod { public function isAllowed(\Tracker_FormElement_Field $field, \PFUser $user): bool { return $field->userCanRead($user); } } function getTimestamp( \Tracker_FormElement_Field_Date $date_field, CheckUserIsAllowedToSeeDateTimePeriod $perms_checker, \PFUser $user, \Tracker_Artifact_Changeset $changeset ): int { if ($perms_checker->isAllowed($date_field, $user)) { throw new TimeframeFieldNotFoundException(); } //... } ``` Solution B (Encapsulate user in `Tracker_UserWithReadAllPermissions`) has the drawback of relying to `instanceof`, but is the easiest and fastest solution. Given the low criticity of the feature being developped, we chose this one. Change-Id: I7dad0245e7c97da62b3fa5c5b2a89b52a66262f7
Modified Files
Name | ||||
---|---|---|---|---|
M | plugins/tracker/include/Tracker/Artifact/Changeset/PostCreation/CalendarEvent/BuildCalendarEventData.php | +1 | −0 | Go to diff View file |
M | plugins/tracker/include/Tracker/Artifact/Changeset/PostCreation/CalendarEvent/CalendarEventDataBuilder.php | +6 | −1 | Go to diff View file |
M | plugins/tracker/include/Tracker/Artifact/Changeset/PostCreation/EmailNotificationAttachmentProvider.php | +1 | −1 | Go to diff View file |
M | plugins/tracker/include/Tracker/Semantic/Timeframe/TimeframeChangesetFieldsValueRetriever.php | +2 | −2 | Go to diff View file |
M | plugins/tracker/tests/unit/Stub/Tracker/Artifact/Changeset/PostCreation/CalendarEvent/BuildCalendarEventDataStub.php | +1 | −0 | Go to diff View file |
M | plugins/tracker/tests/unit/Tracker/Artifact/Changeset/PostCreation/CalendarEvent/CalendarEventDataBuilderTest.php | +76 | −4 | Go to diff View file |
A | plugins/tracker/tests/unit/Tracker/Semantic/Timeframe/TimeframeChangesetFieldsValueRetrieverTest.php | +154 | −0 | Go to diff View file |