diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2026,6 +2026,8 @@ 'PhabricatorCalendarEventCancelTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventCancelTransaction.php', 'PhabricatorCalendarEventDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventDateTransaction.php', 'PhabricatorCalendarEventDeclineTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventDeclineTransaction.php', + 'PhabricatorCalendarEventDefaultEditCapability' => 'applications/calendar/capability/PhabricatorCalendarEventDefaultEditCapability.php', + 'PhabricatorCalendarEventDefaultViewCapability' => 'applications/calendar/capability/PhabricatorCalendarEventDefaultViewCapability.php', 'PhabricatorCalendarEventDescriptionTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventDescriptionTransaction.php', 'PhabricatorCalendarEventDragController' => 'applications/calendar/controller/PhabricatorCalendarEventDragController.php', 'PhabricatorCalendarEventEditConduitAPIMethod' => 'applications/calendar/conduit/PhabricatorCalendarEventEditConduitAPIMethod.php', @@ -2036,11 +2038,13 @@ 'PhabricatorCalendarEventEndDateTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventEndDateTransaction.php', 'PhabricatorCalendarEventFrequencyTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventFrequencyTransaction.php', 'PhabricatorCalendarEventFulltextEngine' => 'applications/calendar/search/PhabricatorCalendarEventFulltextEngine.php', + 'PhabricatorCalendarEventHostPolicyRule' => 'applications/calendar/policyrule/PhabricatorCalendarEventHostPolicyRule.php', 'PhabricatorCalendarEventHostTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventHostTransaction.php', 'PhabricatorCalendarEventIconTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventIconTransaction.php', 'PhabricatorCalendarEventInviteTransaction' => 'applications/calendar/xaction/PhabricatorCalendarEventInviteTransaction.php', 'PhabricatorCalendarEventInvitee' => 'applications/calendar/storage/PhabricatorCalendarEventInvitee.php', 'PhabricatorCalendarEventInviteeQuery' => 'applications/calendar/query/PhabricatorCalendarEventInviteeQuery.php', + 'PhabricatorCalendarEventInviteesPolicyRule' => 'applications/calendar/policyrule/PhabricatorCalendarEventInviteesPolicyRule.php', 'PhabricatorCalendarEventJoinController' => 'applications/calendar/controller/PhabricatorCalendarEventJoinController.php', 'PhabricatorCalendarEventListController' => 'applications/calendar/controller/PhabricatorCalendarEventListController.php', 'PhabricatorCalendarEventMailReceiver' => 'applications/calendar/mail/PhabricatorCalendarEventMailReceiver.php', @@ -6654,6 +6658,8 @@ 'PhabricatorCalendarEventCancelTransaction' => 'PhabricatorCalendarEventTransactionType', 'PhabricatorCalendarEventDateTransaction' => 'PhabricatorCalendarEventTransactionType', 'PhabricatorCalendarEventDeclineTransaction' => 'PhabricatorCalendarEventReplyTransaction', + 'PhabricatorCalendarEventDefaultEditCapability' => 'PhabricatorPolicyCapability', + 'PhabricatorCalendarEventDefaultViewCapability' => 'PhabricatorPolicyCapability', 'PhabricatorCalendarEventDescriptionTransaction' => 'PhabricatorCalendarEventTransactionType', 'PhabricatorCalendarEventDragController' => 'PhabricatorCalendarController', 'PhabricatorCalendarEventEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', @@ -6664,6 +6670,7 @@ 'PhabricatorCalendarEventEndDateTransaction' => 'PhabricatorCalendarEventDateTransaction', 'PhabricatorCalendarEventFrequencyTransaction' => 'PhabricatorCalendarEventTransactionType', 'PhabricatorCalendarEventFulltextEngine' => 'PhabricatorFulltextEngine', + 'PhabricatorCalendarEventHostPolicyRule' => 'PhabricatorPolicyRule', 'PhabricatorCalendarEventHostTransaction' => 'PhabricatorCalendarEventTransactionType', 'PhabricatorCalendarEventIconTransaction' => 'PhabricatorCalendarEventTransactionType', 'PhabricatorCalendarEventInviteTransaction' => 'PhabricatorCalendarEventTransactionType', @@ -6672,6 +6679,7 @@ 'PhabricatorPolicyInterface', ), 'PhabricatorCalendarEventInviteeQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', + 'PhabricatorCalendarEventInviteesPolicyRule' => 'PhabricatorPolicyRule', 'PhabricatorCalendarEventJoinController' => 'PhabricatorCalendarController', 'PhabricatorCalendarEventListController' => 'PhabricatorCalendarController', 'PhabricatorCalendarEventMailReceiver' => 'PhabricatorObjectMailReceiver', diff --git a/src/applications/calendar/application/PhabricatorCalendarApplication.php b/src/applications/calendar/application/PhabricatorCalendarApplication.php --- a/src/applications/calendar/application/PhabricatorCalendarApplication.php +++ b/src/applications/calendar/application/PhabricatorCalendarApplication.php @@ -83,4 +83,19 @@ ); } + protected function getCustomCapabilities() { + return array( + PhabricatorCalendarEventDefaultViewCapability::CAPABILITY => array( + 'caption' => pht('Default view policy for newly created events.'), + 'template' => PhabricatorCalendarEventPHIDType::TYPECONST, + 'capability' => PhabricatorPolicyCapability::CAN_VIEW, + ), + PhabricatorCalendarEventDefaultEditCapability::CAPABILITY => array( + 'caption' => pht('Default edit policy for newly created events.'), + 'template' => PhabricatorCalendarEventPHIDType::TYPECONST, + 'capability' => PhabricatorPolicyCapability::CAN_EDIT, + ), + ); + } + } diff --git a/src/applications/calendar/capability/PhabricatorCalendarEventDefaultEditCapability.php b/src/applications/calendar/capability/PhabricatorCalendarEventDefaultEditCapability.php new file mode 100644 --- /dev/null +++ b/src/applications/calendar/capability/PhabricatorCalendarEventDefaultEditCapability.php @@ -0,0 +1,12 @@ +getTransactionType()) { + case PhabricatorCalendarEventHostTransaction::TRANSACTIONTYPE: + $copy->setHostPHID($xaction->getNewValue()); + break; + case PhabricatorCalendarEventInviteTransaction::TRANSACTIONTYPE: + PhabricatorPolicyRule::passTransactionHintToRule( + $copy, + new PhabricatorCalendarEventInviteesPolicyRule(), + array_fuse($xaction->getNewValue())); + break; + } + } + + return $copy; + } + + protected function applyFinalEffects( PhabricatorLiskDAO $object, array $xactions) { diff --git a/src/applications/calendar/policyrule/PhabricatorCalendarEventHostPolicyRule.php b/src/applications/calendar/policyrule/PhabricatorCalendarEventHostPolicyRule.php new file mode 100644 --- /dev/null +++ b/src/applications/calendar/policyrule/PhabricatorCalendarEventHostPolicyRule.php @@ -0,0 +1,43 @@ +getPHID(); + if (!$viewer_phid) { + return false; + } + + return ($object->getHostPHID() == $viewer_phid); + } + + public function getValueControlType() { + return self::CONTROL_TYPE_NONE; + } + +} diff --git a/src/applications/calendar/policyrule/PhabricatorCalendarEventInviteesPolicyRule.php b/src/applications/calendar/policyrule/PhabricatorCalendarEventInviteesPolicyRule.php new file mode 100644 --- /dev/null +++ b/src/applications/calendar/policyrule/PhabricatorCalendarEventInviteesPolicyRule.php @@ -0,0 +1,104 @@ +getPHID(); + if (!$viewer_phid) { + return; + } + + if (empty($this->invited[$viewer_phid])) { + $this->invited[$viewer_phid] = array(); + } + + if (!isset($this->sourcePHIDs[$viewer_phid])) { + $source_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( + $viewer_phid, + PhabricatorProjectMemberOfProjectEdgeType::EDGECONST); + $source_phids[] = $viewer_phid; + $this->sourcePHIDs[$viewer_phid] = $source_phids; + } + + foreach ($objects as $key => $object) { + $cache = $this->getTransactionHint($object); + if ($cache === null) { + // We don't have a hint for this object, so we'll deal with it below. + continue; + } + + // We have a hint, so use that as the source of truth. + unset($objects[$key]); + + foreach ($this->sourcePHIDs[$viewer_phid] as $source_phid) { + if (isset($cache[$source_phid])) { + $this->invited[$viewer_phid][$object->getPHID()] = true; + break; + } + } + } + + $phids = mpull($objects, 'getPHID'); + if (!$phids) { + return; + } + + $invited = id(new PhabricatorCalendarEventInvitee())->loadAllWhere( + 'eventPHID IN (%Ls) + AND inviteePHID IN (%Ls) + AND status != %s', + $phids, + $this->sourcePHIDs[$viewer_phid], + PhabricatorCalendarEventInvitee::STATUS_UNINVITED); + $invited = mpull($invited, 'getEventPHID'); + + $this->invited[$viewer_phid] += array_fill_keys($invited, true); + } + + public function applyRule( + PhabricatorUser $viewer, + $value, + PhabricatorPolicyInterface $object) { + + $viewer_phid = $viewer->getPHID(); + if (!$viewer_phid) { + return false; + } + + $invited = idx($this->invited, $viewer_phid); + return isset($invited[$object->getPHID()]); + } + + public function getValueControlType() { + return self::CONTROL_TYPE_NONE; + } + +} diff --git a/src/applications/calendar/storage/PhabricatorCalendarEvent.php b/src/applications/calendar/storage/PhabricatorCalendarEvent.php --- a/src/applications/calendar/storage/PhabricatorCalendarEvent.php +++ b/src/applications/calendar/storage/PhabricatorCalendarEvent.php @@ -57,7 +57,10 @@ ->withClasses(array('PhabricatorCalendarApplication')) ->executeOne(); - $view_policy = PhabricatorPolicies::getMostOpenPolicy(); + $view_default = PhabricatorCalendarEventDefaultViewCapability::CAPABILITY; + $edit_default = PhabricatorCalendarEventDefaultEditCapability::CAPABILITY; + $view_policy = $app->getPolicy($view_default); + $edit_policy = $app->getPolicy($edit_default); $start = new DateTime('@'.PhabricatorTime::getNow()); $start->setTimeZone($actor->getTimeZone()); @@ -83,7 +86,7 @@ )) ->setIcon($default_icon) ->setViewPolicy($view_policy) - ->setEditPolicy($actor->getPHID()) + ->setEditPolicy($edit_policy) ->setSpacePHID($actor->getDefaultSpacePHID()) ->attachInvitees(array()) ->setDateFrom($epoch_min)