From c6569e7dc70ac07db5d86e429d7f3d0d42792915 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Gerg=C5=91=20Tisza?= Date: Wed, 7 Sep 2016 05:50:35 +0000 Subject: [PATCH] Hide signup/login/logout links when they would not work Immutable session providers do not support login and logout; these pages would just show an error when such a session provider is handling the authentication of the request. Depending on what authentication providers are configured, the wiki might not support account creation. Showing the links is unhelpful if they would just show an obscure error message. (OTOH don't try to hide the link when the reason it is not usable depends on the user; specifically, don't check AuthManager::checkAccountCreatePermissions. An error message is more informative in that case than a missing link.) Also improve how the affected special pages behave if the user manages to get there anyway. Change-Id: Ic0ad237259797a8d471bdabc57a4bd0ffe8fa33b --- includes/skins/SkinTemplate.php | 39 +++++++++++++------ .../specialpage/LoginSignupSpecialPage.php | 11 ++++-- languages/i18n/en.json | 4 ++ languages/i18n/qqq.json | 8 +++- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/includes/skins/SkinTemplate.php b/includes/skins/SkinTemplate.php index 9e79c29f7d..f18578959e 100644 --- a/includes/skins/SkinTemplate.php +++ b/includes/skins/SkinTemplate.php @@ -17,6 +17,8 @@ * * @file */ + +use MediaWiki\Auth\AuthManager; use MediaWiki\MediaWikiServices; /** @@ -574,6 +576,7 @@ class SkinTemplate extends Skin { $title = $this->getTitle(); $request = $this->getRequest(); $pageurl = $title->getLocalURL(); + $authManager = AuthManager::singleton(); /* set up the default links for the personal toolbar */ $personal_urls = []; @@ -652,17 +655,25 @@ class SkinTemplate extends Skin { 'href' => $href, 'active' => $active ]; - $personal_urls['logout'] = [ - 'text' => $this->msg( 'pt-userlogout' )->text(), - 'href' => self::makeSpecialUrl( 'Userlogout', - // userlogout link must always contain an & character, otherwise we might not be able - // to detect a buggy precaching proxy (bug 17790) - $title->isSpecial( 'Preferences' ) ? 'noreturnto' : $returnto - ), - 'active' => false - ]; + + // if we can't set the user, we can't unset it either + if ( $request->getSession()->canSetUser() ) { + $personal_urls['logout'] = [ + 'text' => $this->msg( 'pt-userlogout' )->text(), + 'href' => self::makeSpecialUrl( 'Userlogout', + // userlogout link must always contain an & character, otherwise we might not be able + // to detect a buggy precaching proxy (bug 17790) + $title->isSpecial( 'Preferences' ) ? 'noreturnto' : $returnto ), + 'active' => false + ]; + } } else { $useCombinedLoginLink = $this->useCombinedLoginLink(); + if ( !$authManager->canCreateAccounts() || !$authManager->canAuthenticateNow() ) { + // don't show combined login/signup link if one of those is actually not available + $useCombinedLoginLink = false; + } + $loginlink = $this->getUser()->isAllowed( 'createaccount' ) && $useCombinedLoginLink ? 'nav-login-createaccount' : 'pt-login'; @@ -699,11 +710,17 @@ class SkinTemplate extends Skin { ]; } - if ( $this->getUser()->isAllowed( 'createaccount' ) && !$useCombinedLoginLink ) { + if ( + $authManager->canCreateAccounts() + && $this->getUser()->isAllowed( 'createaccount' ) + && !$useCombinedLoginLink + ) { $personal_urls['createaccount'] = $createaccount_url; } - $personal_urls['login'] = $login_url; + if ( $authManager->canAuthenticateNow() ) { + $personal_urls['login'] = $login_url; + } } Hooks::run( 'PersonalUrls', [ &$personal_urls, &$title, $this ] ); diff --git a/includes/specialpage/LoginSignupSpecialPage.php b/includes/specialpage/LoginSignupSpecialPage.php index c3d43df266..9d17e7dc57 100644 --- a/includes/specialpage/LoginSignupSpecialPage.php +++ b/includes/specialpage/LoginSignupSpecialPage.php @@ -223,11 +223,16 @@ abstract class LoginSignupSpecialPage extends AuthManagerSpecialPage { $this->setHeaders(); $this->checkPermissions(); - // Make sure it's possible to log in - if ( !$this->isSignup() && !$session->canSetUser() ) { - throw new ErrorPageError( 'cannotloginnow-title', 'cannotloginnow-text', [ + // Make sure the system configuration allows log in / sign up + if ( !$this->isSignup() && !$authManager->canAuthenticateNow() ) { + if ( !$session->canSetUser() ) { + throw new ErrorPageError( 'cannotloginnow-title', 'cannotloginnow-text', [ $session->getProvider()->describe( RequestContext::getMain()->getLanguage() ) ] ); + } + throw new ErrorPageError( 'cannotlogin-title', 'cannotlogin-text' ); + } elseif ( $this->isSignup() && !$authManager->canCreateAccounts() ) { + throw new ErrorPageError( 'cannotcreateaccount-title', 'cannotcreateaccount-text' ); } /* diff --git a/languages/i18n/en.json b/languages/i18n/en.json index 020f058907..0f4e98eba9 100644 --- a/languages/i18n/en.json +++ b/languages/i18n/en.json @@ -410,8 +410,12 @@ "createacct-yourpasswordagain-ph": "Enter password again", "userlogin-remembermypassword": "Keep me logged in", "userlogin-signwithsecure": "Use secure connection", + "cannotlogin-title": "Cannot log in", + "cannotlogin-text": "Logging in is not possible.", "cannotloginnow-title": "Cannot log in now", "cannotloginnow-text": "Logging in is not possible when using $1.", + "cannotcreateaccount-title": "Cannot create accounts", + "cannotcreateaccount-text": "Direct account creation is not enabled on this wiki.", "yourdomainname": "Your domain:", "password-change-forbidden": "You cannot change passwords on this wiki.", "externaldberror": "There was either an authentication database error or you are not allowed to update your external account.", diff --git a/languages/i18n/qqq.json b/languages/i18n/qqq.json index 388de6eb67..7b93742367 100644 --- a/languages/i18n/qqq.json +++ b/languages/i18n/qqq.json @@ -594,8 +594,12 @@ "createacct-yourpasswordagain-ph": "Placeholder text in create account form for re-enter password field.\n\nSee example: [{{canonicalurl:Special:UserLogin|type=signup}} Special:UserLogin?type=signup]", "userlogin-remembermypassword": "Used as checkbox label in [[Special:UserLogin]]. Parameters:\n* $1 - number of days the login session will be active if checked (Unused but used on-wiki)\n", "userlogin-signwithsecure": "Text of link to HTTPS login form.\n\nSee example: [[Special:UserLogin]]", - "cannotloginnow-title": "Error page title shown when logging in is not possible.", - "cannotloginnow-text": "Error page text shown when logging in is not possible. Parameters:\n* $1 - Session type in use that makes it not possible to log in, from a message like {{msg-mw|sessionprovider-mediawiki-session-cookiesessionprovider}}.", + "cannotlogin-title": "Error page title shown when logging in is not possible. This is a catch-all when a more specific reason is not available.", + "cannotlogin-text": "Error page text shown when logging in is not possible. This is a catch-all when a more specific reason is not available.", + "cannotloginnow-title": "Error page title shown when logging in is not possible becuse the session provider in use does the user authentication itself.", + "cannotloginnow-text": "Error page text shown when logging in is not possible becuse the session provider in use does the user authentication itself. Parameters:\n* $1 - Session type in use that makes it not possible to log in, from a message like {{msg-mw|sessionprovider-mediawiki-session-cookiesessionprovider}}.", + "cannotcreateaccount-title": "Error page title shown when manual account creation is not possible. That probably means the wiki supports some other account creation method, e.g. autocreation by the session provider. (When account creation is possible but the current user does not have permission to do it, a more specific error message is displayed.)", + "cannotcreateaccount-text": "Error page text shown when manual account creation is not possible. That probably means the wiki supports some other account creation method, e.g. autocreation by the session provider. (When account creation is possible but the current user does not have permission to do it, a more specific error message is displayed.)", "yourdomainname": "Used as label for listbox.", "password-change-forbidden": "Error message shown when an external authentication source does not allow the password to be changed.", "externaldberror": "This message is thrown when a valid attempt to change the wiki password for a user fails because of a database error or an error from an external system.", -- 2.20.1