@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Don't show personalized menu items until users establish a full session

Summary:
Depends on D18792. Fixes T13024. Fixes T89198. Currently, when users are logging in initially (for example, need to enter MFA) we show more menu items than we should.

Notably, we may show some personalized/private account details, like the number of unread notifications (probably not relevant) or a user's saved queries (possibly sensitive). At best these are misleading (they won't work yet) and there's an outside possibility they leak a little bit of private data.

Instead, nuke everything except "Log Out" when users have partial sessions.

Test Plan:
Hit a partial session (MFA required, email verification required) and looked at the menu. Only saw "Log Out".

{F5297713}

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13024

Differential Revision: https://secure.phabricator.com/D18793

+106 -32
+4
src/applications/files/controller/PhabricatorFileDataController.php
··· 10 10 return false; 11 11 } 12 12 13 + public function shouldAllowPartialSessions() { 14 + return true; 15 + } 16 + 13 17 public function handleRequest(AphrontRequest $request) { 14 18 $viewer = $request->getViewer(); 15 19 $this->phid = $request->getURIData('phid');
+34 -28
src/applications/people/engineextension/PeopleMainMenuBarExtension.php
··· 9 9 return $viewer->isLoggedIn(); 10 10 } 11 11 12 + public function shouldAllowPartialSessions() { 13 + return true; 14 + } 15 + 12 16 public function getExtensionOrder() { 13 17 return 1200; 14 18 } ··· 65 69 $view = id(new PhabricatorActionListView()) 66 70 ->setViewer($viewer); 67 71 68 - $view->addAction( 69 - id(new PhabricatorActionView()) 70 - ->appendChild($user_view)); 72 + if ($this->getIsFullSession()) { 73 + $view->addAction( 74 + id(new PhabricatorActionView()) 75 + ->appendChild($user_view)); 71 76 72 - $view->addAction( 73 - id(new PhabricatorActionView()) 74 - ->setType(PhabricatorActionView::TYPE_DIVIDER)); 77 + $view->addAction( 78 + id(new PhabricatorActionView()) 79 + ->setType(PhabricatorActionView::TYPE_DIVIDER)); 75 80 76 - $view->addAction( 77 - id(new PhabricatorActionView()) 78 - ->setName(pht('Profile')) 79 - ->setHref('/p/'.$viewer->getUsername().'/')); 81 + $view->addAction( 82 + id(new PhabricatorActionView()) 83 + ->setName(pht('Profile')) 84 + ->setHref('/p/'.$viewer->getUsername().'/')); 80 85 81 - $view->addAction( 82 - id(new PhabricatorActionView()) 83 - ->setName(pht('Settings')) 84 - ->setHref('/settings/user/'.$viewer->getUsername().'/')); 86 + $view->addAction( 87 + id(new PhabricatorActionView()) 88 + ->setName(pht('Settings')) 89 + ->setHref('/settings/user/'.$viewer->getUsername().'/')); 85 90 86 - $view->addAction( 87 - id(new PhabricatorActionView()) 88 - ->setName(pht('Manage')) 89 - ->setHref('/people/manage/'.$viewer->getID().'/')); 91 + $view->addAction( 92 + id(new PhabricatorActionView()) 93 + ->setName(pht('Manage')) 94 + ->setHref('/people/manage/'.$viewer->getID().'/')); 90 95 91 - if ($application) { 92 - $help_links = $application->getHelpMenuItems($viewer); 93 - if ($help_links) { 94 - foreach ($help_links as $link) { 95 - $view->addAction($link); 96 + if ($application) { 97 + $help_links = $application->getHelpMenuItems($viewer); 98 + if ($help_links) { 99 + foreach ($help_links as $link) { 100 + $view->addAction($link); 101 + } 96 102 } 97 103 } 98 - } 99 104 100 - $view->addAction( 101 - id(new PhabricatorActionView()) 102 - ->addSigil('logout-item') 103 - ->setType(PhabricatorActionView::TYPE_DIVIDER)); 105 + $view->addAction( 106 + id(new PhabricatorActionView()) 107 + ->addSigil('logout-item') 108 + ->setType(PhabricatorActionView::TYPE_DIVIDER)); 109 + } 104 110 105 111 $view->addAction( 106 112 id(new PhabricatorActionView())
+14
src/view/page/menu/PhabricatorMainMenuBarExtension.php
··· 5 5 private $viewer; 6 6 private $application; 7 7 private $controller; 8 + private $isFullSession; 8 9 9 10 public function setViewer(PhabricatorUser $viewer) { 10 11 $this->viewer = $viewer; ··· 33 34 return $this->controller; 34 35 } 35 36 37 + public function setIsFullSession($is_full_session) { 38 + $this->isFullSession = $is_full_session; 39 + return $this; 40 + } 41 + 42 + public function getIsFullSession() { 43 + return $this->isFullSession; 44 + } 45 + 36 46 final public function getExtensionKey() { 37 47 return $this->getPhobjectClassConstant('MAINMENUBARKEY'); 38 48 } 39 49 40 50 public function isExtensionEnabled() { 41 51 return true; 52 + } 53 + 54 + public function shouldAllowPartialSessions() { 55 + return false; 42 56 } 43 57 44 58 public function isExtensionEnabledForViewer(PhabricatorUser $viewer) {
+54 -4
src/view/page/menu/PhabricatorMainMenuView.php
··· 46 46 $app_button = ''; 47 47 $aural = null; 48 48 49 - if ($viewer->isLoggedIn() && $viewer->isUserActivated()) { 49 + $is_full = $this->isFullSession($viewer); 50 + 51 + if ($is_full) { 50 52 list($menu, $dropdowns, $aural) = $this->renderNotificationMenu(); 51 53 if (array_filter($menu)) { 52 54 $alerts[] = $menu; ··· 54 56 $menu_bar = array_merge($menu_bar, $dropdowns); 55 57 $app_button = $this->renderApplicationMenuButton(); 56 58 $search_button = $this->renderSearchMenuButton($header_id); 57 - } else { 59 + } else if (!$viewer->isLoggedIn()) { 58 60 $app_button = $this->renderApplicationMenuButton(); 59 61 if (PhabricatorEnv::getEnvConfig('policy.allow-public')) { 60 62 $search_button = $this->renderSearchMenuButton($header_id); 61 63 } 62 64 } 63 65 64 - $search_menu = $this->renderPhabricatorSearchMenu(); 66 + if ($search_button) { 67 + $search_menu = $this->renderPhabricatorSearchMenu(); 68 + } else { 69 + $search_menu = null; 70 + } 65 71 66 72 if ($alerts) { 67 73 $alerts = javelin_tag( ··· 84 90 85 91 $extensions = PhabricatorMainMenuBarExtension::getAllEnabledExtensions(); 86 92 foreach ($extensions as $extension) { 87 - $extension->setViewer($viewer); 93 + $extension 94 + ->setViewer($viewer) 95 + ->setIsFullSession($is_full); 88 96 89 97 $controller = $this->getController(); 90 98 if ($controller) { ··· 92 100 $application = $controller->getCurrentApplication(); 93 101 if ($application) { 94 102 $extension->setApplication($application); 103 + } 104 + } 105 + } 106 + 107 + if (!$is_full) { 108 + foreach ($extensions as $key => $extension) { 109 + if (!$extension->shouldAllowPartialSessions()) { 110 + unset($extensions[$key]); 95 111 } 96 112 } 97 113 } ··· 675 691 $dropdowns, 676 692 $aural, 677 693 ); 694 + } 695 + 696 + private function isFullSession(PhabricatorUser $viewer) { 697 + if (!$viewer->isLoggedIn()) { 698 + return false; 699 + } 700 + 701 + if (!$viewer->isUserActivated()) { 702 + return false; 703 + } 704 + 705 + if (!$viewer->hasSession()) { 706 + return false; 707 + } 708 + 709 + $session = $viewer->getSession(); 710 + if ($session->getIsPartial()) { 711 + return false; 712 + } 713 + 714 + if (!$session->getSignedLegalpadDocuments()) { 715 + return false; 716 + } 717 + 718 + $mfa_key = 'security.require-multi-factor-auth'; 719 + $need_mfa = PhabricatorEnv::getEnvConfig($mfa_key); 720 + if ($need_mfa) { 721 + $have_mfa = $viewer->getIsEnrolledInMultiFactor(); 722 + if (!$have_mfa) { 723 + return false; 724 + } 725 + } 726 + 727 + return true; 678 728 } 679 729 680 730 }