public function getSearchFields($object) { $fields = array(); if (PhabricatorSpacesNamespaceQuery::getSpacesExist()) { $fields[] = id(new PhabricatorSpacesSearchField())->setKey('spacePHIDs')->setConduitKey('spaces')->setAliases(array('space', 'spaces'))->setLabel(pht('Spaces'))->setDescription(pht('Search for objects in certain spaces.')); } return $fields; }
private function appendSpaceInformation(AphrontDialogView $dialog, PhabricatorPolicyInterface $object, PhabricatorPolicy $policy, $capability) { $viewer = $this->getViewer(); if (!$object instanceof PhabricatorSpacesInterface) { return; } if (!PhabricatorSpacesNamespaceQuery::getSpacesExist($viewer)) { return; } // NOTE: We're intentionally letting users through here, even if they only // have access to one space. The intent is to help users in "space jail" // understand who objects they create are visible to: $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($object); $handles = $viewer->loadHandles(array($space_phid)); $doc_href = PhabricatorEnv::getDoclink('Spaces User Guide'); $dialog->appendParagraph(array(pht('This object is in %s, and can only be seen or edited by users with ' . 'access to view objects in the space.', $handles[$space_phid]->renderLink()), ' ', phutil_tag('strong', array(), phutil_tag('a', array('href' => $doc_href, 'target' => '_blank'), pht('Learn More'))))); $spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer); $space = idx($spaces, $space_phid); if (!$space) { return; } $space_policies = PhabricatorPolicyQuery::loadPolicies($viewer, $space); $space_policy = idx($space_policies, PhabricatorPolicyCapability::CAN_VIEW); if (!$space_policy) { return; } $space_explanation = PhabricatorPolicy::getPolicyExplanation($viewer, $space_policy->getPHID()); $items = array(); $items[] = $space_explanation; foreach ($items as $key => $item) { $items[$key] = phutil_tag('li', array(), $item); } $dialog->appendParagraph(pht('Users who can see objects in this space:')); $dialog->appendChild(phutil_tag('ul', array(), $items)); $view_capability = PhabricatorPolicyCapability::CAN_VIEW; if ($capability == $view_capability) { $stronger = $space_policy->isStrongerThan($policy); if ($stronger) { $dialog->appendParagraph(pht('The space this object is in has a more restrictive view ' . 'policy ("%s") than the object does ("%s"), so the space\'s ' . 'view policy is shown as a hint instead of the object policy.', $space_policy->getShortName(), $policy->getShortName())); } } $dialog->appendParagraph(pht('After a user passes space policy checks, they must still pass ' . 'object policy checks.')); }
private function buildSpaceSection(PhabricatorPolicyInterface $object, PhabricatorPolicy $policy, $capability) { $viewer = $this->getViewer(); if (!$object instanceof PhabricatorSpacesInterface) { return null; } if (!PhabricatorSpacesNamespaceQuery::getSpacesExist($viewer)) { return null; } $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID($object); $spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($viewer); $space = idx($spaces, $space_phid); if (!$space) { return null; } $space_policies = PhabricatorPolicyQuery::loadPolicies($viewer, $space); $space_policy = idx($space_policies, PhabricatorPolicyCapability::CAN_VIEW); if (!$space_policy) { return null; } $doc_href = PhabricatorEnv::getDoclink('Spaces User Guide'); $capability_name = $this->getCapabilityName($capability); $space_section = id(new PHUIPolicySectionView())->setViewer($viewer)->setIcon('fa-th-large bluegrey')->setHeader(pht('Space'))->setDocumentationLink(pht('Spaces Documentation'), $doc_href)->appendList(array(array(phutil_tag('strong', array(), pht('Space:')), ' ', $viewer->renderHandle($space_phid)->setAsTag(true)), array(phutil_tag('strong', array(), pht('%s:', $capability_name)), ' ', $space_policy->getShortName())))->appendParagraph(pht('This object is in %s and can only be seen or edited by users ' . 'with access to view objects in the space.', $viewer->renderHandle($space_phid))); $space_explanation = PhabricatorPolicy::getPolicyExplanation($viewer, $space_policy->getPHID()); $items = array(); $items[] = $space_explanation; $space_section->appendParagraph(pht('Users who can see objects in this space:'))->appendList($items); $view_capability = PhabricatorPolicyCapability::CAN_VIEW; if ($capability == $view_capability) { $stronger = $space_policy->isStrongerThan($policy); if ($stronger) { $space_section->appendHint(pht('The space this object is in has a more restrictive view ' . 'policy ("%s") than the object does ("%s"), so the space\'s ' . 'view policy is shown as a hint instead of the object policy.', $space_policy->getShortName(), $policy->getShortName())); } } $space_section->appendHint(pht('After a user passes space policy checks, they must still pass ' . 'object policy checks.')); return $space_section; }
public function willBeginExecution() { $request = $this->getRequest(); if ($request->getUser()) { // NOTE: Unit tests can set a user explicitly. Normal requests are not // permitted to do this. PhabricatorTestCase::assertExecutingUnitTests(); $user = $request->getUser(); } else { $user = new PhabricatorUser(); $session_engine = new PhabricatorAuthSessionEngine(); $phsid = $request->getCookie(PhabricatorCookies::COOKIE_SESSION); if (strlen($phsid)) { $session_user = $session_engine->loadUserForSession(PhabricatorAuthSession::TYPE_WEB, $phsid); if ($session_user) { $user = $session_user; } } else { // If the client doesn't have a session token, generate an anonymous // session. This is used to provide CSRF protection to logged-out users. $phsid = $session_engine->establishSession(PhabricatorAuthSession::TYPE_WEB, null, $partial = false); // This may be a resource request, in which case we just don't set // the cookie. if ($request->canSetCookies()) { $request->setCookie(PhabricatorCookies::COOKIE_SESSION, $phsid); } } if (!$user->isLoggedIn()) { $user->attachAlternateCSRFString(PhabricatorHash::digest($phsid)); } $request->setUser($user); } PhabricatorEnv::setLocaleCode($user->getTranslation()); $preferences = $user->loadPreferences(); if (PhabricatorEnv::getEnvConfig('darkconsole.enabled')) { $dark_console = PhabricatorUserPreferences::PREFERENCE_DARK_CONSOLE; if ($preferences->getPreference($dark_console) || PhabricatorEnv::getEnvConfig('darkconsole.always-on')) { $console = new DarkConsoleCore(); $request->getApplicationConfiguration()->setConsole($console); } } // NOTE: We want to set up the user first so we can render a real page // here, but fire this before any real logic. $restricted = array('code'); foreach ($restricted as $parameter) { if ($request->getExists($parameter)) { if (!$this->shouldAllowRestrictedParameter($parameter)) { throw new Exception(pht('Request includes restricted parameter "%s", but this ' . 'controller ("%s") does not whitelist it. Refusing to ' . 'serve this request because it might be part of a redirection ' . 'attack.', $parameter, get_class($this))); } } } if ($this->shouldRequireEnabledUser()) { if ($user->isLoggedIn() && !$user->getIsApproved()) { $controller = new PhabricatorAuthNeedsApprovalController(); return $this->delegateToController($controller); } if ($user->getIsDisabled()) { $controller = new PhabricatorDisabledUserController(); return $this->delegateToController($controller); } } $auth_class = 'PhabricatorAuthApplication'; $auth_application = PhabricatorApplication::getByClass($auth_class); // Require partial sessions to finish login before doing anything. if (!$this->shouldAllowPartialSessions()) { if ($user->hasSession() && $user->getSession()->getIsPartial()) { $login_controller = new PhabricatorAuthFinishController(); $this->setCurrentApplication($auth_application); return $this->delegateToController($login_controller); } } // Check if the user needs to configure MFA. $need_mfa = $this->shouldRequireMultiFactorEnrollment(); $have_mfa = $user->getIsEnrolledInMultiFactor(); if ($need_mfa && !$have_mfa) { // Check if the cache is just out of date. Otherwise, roadblock the user // and require MFA enrollment. $user->updateMultiFactorEnrollment(); if (!$user->getIsEnrolledInMultiFactor()) { $mfa_controller = new PhabricatorAuthNeedsMultiFactorController(); $this->setCurrentApplication($auth_application); return $this->delegateToController($mfa_controller); } } if ($this->shouldRequireLogin()) { // This actually means we need either: // - a valid user, or a public controller; and // - permission to see the application; and // - permission to see at least one Space if spaces are configured. $allow_public = $this->shouldAllowPublic() && PhabricatorEnv::getEnvConfig('policy.allow-public'); // If this controller isn't public, and the user isn't logged in, require // login. if (!$allow_public && !$user->isLoggedIn()) { $login_controller = new PhabricatorAuthStartController(); $this->setCurrentApplication($auth_application); return $this->delegateToController($login_controller); } if ($user->isLoggedIn()) { if ($this->shouldRequireEmailVerification()) { if (!$user->getIsEmailVerified()) { $controller = new PhabricatorMustVerifyEmailController(); $this->setCurrentApplication($auth_application); return $this->delegateToController($controller); } } } // If Spaces are configured, require that the user have access to at // least one. If we don't do this, they'll get confusing error messages // later on. $spaces = PhabricatorSpacesNamespaceQuery::getSpacesExist(); if ($spaces) { $viewer_spaces = PhabricatorSpacesNamespaceQuery::getViewerSpaces($user); if (!$viewer_spaces) { $controller = new PhabricatorSpacesNoAccessController(); return $this->delegateToController($controller); } } // If the user doesn't have access to the application, don't let them use // any of its controllers. We query the application in order to generate // a policy exception if the viewer doesn't have permission. $application = $this->getCurrentApplication(); if ($application) { id(new PhabricatorApplicationQuery())->setViewer($user)->withPHIDs(array($application->getPHID()))->executeOne(); } } if (!$this->shouldAllowLegallyNonCompliantUsers()) { $legalpad_class = 'PhabricatorLegalpadApplication'; $legalpad = id(new PhabricatorApplicationQuery())->setViewer($user)->withClasses(array($legalpad_class))->withInstalled(true)->execute(); $legalpad = head($legalpad); $doc_query = id(new LegalpadDocumentQuery())->setViewer($user)->withSignatureRequired(1)->needViewerSignatures(true); if ($user->hasSession() && !$user->getSession()->getIsPartial() && !$user->getSession()->getSignedLegalpadDocuments() && $user->isLoggedIn() && $legalpad) { $sign_docs = $doc_query->execute(); $must_sign_docs = array(); foreach ($sign_docs as $sign_doc) { if (!$sign_doc->getUserSignature($user->getPHID())) { $must_sign_docs[] = $sign_doc; } } if ($must_sign_docs) { $controller = new LegalpadDocumentSignController(); $this->getRequest()->setURIMap(array('id' => head($must_sign_docs)->getID())); $this->setCurrentApplication($legalpad); return $this->delegateToController($controller); } else { $engine = id(new PhabricatorAuthSessionEngine())->signLegalpadDocuments($user, $sign_docs); } } } // NOTE: We do this last so that users get a login page instead of a 403 // if they need to login. if ($this->shouldRequireAdmin() && !$user->getIsAdmin()) { return new Aphront403Response(); } }
protected function buildSearchFields() { $fields = array(); foreach ($this->buildCustomSearchFields() as $field) { $fields[] = $field; } $object = $this->newResultObject(); if ($object) { if ($object instanceof PhabricatorSubscribableInterface) { $fields[] = id(new PhabricatorSearchSubscribersField())->setLabel(pht('Subscribers'))->setKey('subscriberPHIDs')->setAliases(array('subscriber', 'subscribers')); } if ($object instanceof PhabricatorProjectInterface) { $fields[] = id(new PhabricatorProjectSearchField())->setKey('projectPHIDs')->setAliases(array('project', 'projects'))->setLabel(pht('Projects')); } if ($object instanceof PhabricatorSpacesInterface) { if (PhabricatorSpacesNamespaceQuery::getSpacesExist()) { $fields[] = id(new PhabricatorSpacesSearchField())->setKey('spacePHIDs')->setAliases(array('space', 'spaces'))->setLabel(pht('Spaces')); } } } foreach ($this->buildCustomFieldSearchFields() as $custom_field) { $fields[] = $custom_field; } $query = $this->newQuery(); if ($query && $this->shouldShowOrderField()) { $orders = $query->getBuiltinOrders(); $orders = ipull($orders, 'name'); $fields[] = id(new PhabricatorSearchOrderField())->setLabel(pht('Order By'))->setKey('order')->setOrderAliases($query->getBuiltinOrderAliasMap())->setOptions($orders); } $field_map = array(); foreach ($fields as $field) { $key = $field->getKey(); if (isset($field_map[$key])) { throw new Exception(pht('Two fields in this SearchEngine use the same key ("%s"), but ' . 'each field must use a unique key.', $key)); } $field_map[$key] = $field; } return $field_map; }