Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F1430547
SharedDomainUtils.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
SharedDomainUtils.php
View Options
<?php
namespace
MediaWiki\Extension\CentralAuth
;
use
MediaWiki\Config\Config
;
use
MediaWiki\Extension\CentralAuth\Hooks\Handlers\SsoHookHandler
;
use
MediaWiki\Request\WebRequest
;
use
MediaWiki\Title\TitleFactory
;
use
MediaWiki\WikiMap\WikiMap
;
use
MobileContext
;
use
RuntimeException
;
use
Wikimedia\Assert\Assert
;
/**
* Utilities for handling the shared domain name used for SUL3 login.
* This class is kept lightweight, so it can be used in early hooks.
*/
class
SharedDomainUtils
{
private
const
SUL3_COOKIE_FLAG
=
'sul3OptIn'
;
private
Config
$config
;
private
TitleFactory
$titleFactory
;
private
bool
$isSharedDomain
;
private
?
MobileContext
$mobileContext
=
null
;
public
function
__construct
(
Config
$config
,
TitleFactory
$titleFactory
,
?
MobileContext
$mobileContext
=
null
)
{
$this
->
config
=
$config
;
$this
->
titleFactory
=
$titleFactory
;
$this
->
mobileContext
=
$mobileContext
;
}
/**
* Whether the current request is to the shared domain used for SUL3 login.
*
* This assumes:
* - $wgCentralAuthSsoUrlPrefix contains the shared domain.
* - $wgCanonicalServer is set in site configuration to the current domain
* (instead of the actual canonical domain) for requests to the shared domain.
*
* @return bool
*/
public
function
isSharedDomain
():
bool
{
// @phan-suppress-next-line PhanRedundantCondition
if
(
!
isset
(
$this
->
isSharedDomain
)
)
{
$centralAuthSsoUrlPrefix
=
$this
->
config
->
get
(
'CentralAuthSsoUrlPrefix'
);
if
(
!
$centralAuthSsoUrlPrefix
)
{
$this
->
isSharedDomain
=
false
;
}
else
{
$sharedDomain
=
parse_url
(
$centralAuthSsoUrlPrefix
,
PHP_URL_HOST
);
$currentDomain
=
parse_url
(
$this
->
config
->
get
(
'CanonicalServer'
),
PHP_URL_HOST
);
$this
->
isSharedDomain
=
$sharedDomain
&&
$currentDomain
===
$sharedDomain
;
}
}
return
$this
->
isSharedDomain
;
}
/**
* Whether the current request must deny non-auth actions.
*
* If $wgCentralAuthRestrictSsoDomain is enabled, then requests to the "fake"
* shared domain within $wgCentralAuthSsoUrlPrefix must only be for authentication
* purposes. All non-authentication-related actions should be prevented.
*
* SUL3 login supports both using a dedicated login wiki for the domain where the central
* session cookies are stored, and a shared domain which serve any wiki (from a virtual
* sub directory). In the latter case, we want to prevent non-authentication actions
* to prevent complications like cache splits. This flag differentiates between the two
* setups.
*
* @return bool
* @see SsoHookHandler
*/
public
function
shouldRestrictCurrentDomain
():
bool
{
return
$this
->
isSharedDomain
()
&&
$this
->
config
->
get
(
'CentralAuthRestrictSsoDomain'
);
}
/**
* Whether SUL3 mode is enabled on this wiki and/or this request.
*
* In order to facilitate testing of SUL3 migration, this method
* provides mechanisms for testing the SUL3 feature including a
* cookie-based feature flag.
*
* SUL3 mode is enabled if any of the following conditions is true:
* - $wgCentralAuthEnableSul3 contains 'always'
* - $wgCentralAuthEnableSul3 contains 'cookie' and there is a
* cookie named 'sul3OptIn' with the value '1'
* - $wgCentralAuthEnableSul3 contains 'query-flag' and the URL has
* a query parameter 'usesul3' with a truthy value
*
* @param WebRequest $request
* @return bool
*/
public
function
isSul3Enabled
(
WebRequest
$request
):
bool
{
$sul3Config
=
$this
->
config
->
get
(
'CentralAuthEnableSul3'
);
// For B/C, this config was a string before. Now that we're moving
// to an array based value, we need to support both while migrating.
// TEMPORARY: Remove this code below once migration is complete.
if
(
$sul3Config
===
false
)
{
$sul3Config
=
[];
}
elseif
(
!
is_array
(
$sul3Config
)
)
{
$sul3Config
=
[
$sul3Config
];
}
if
(
in_array
(
'always'
,
$sul3Config
,
true
)
)
{
return
true
;
}
elseif
(
in_array
(
'cookie'
,
$sul3Config
,
true
)
&&
$request
->
getCookie
(
self
::
SUL3_COOKIE_FLAG
,
''
)
===
'1'
)
{
return
true
;
}
elseif
(
in_array
(
'query-flag'
,
$sul3Config
,
true
)
&&
$request
->
getCheck
(
'usesul3'
)
)
{
return
true
;
}
else
{
return
false
;
}
}
/**
* Assert that the SUL3 mode is allowed.
*
* @param WebRequest $request
* @return void
*/
public
function
assertSul3Enabled
(
WebRequest
$request
)
{
Assert
::
precondition
(
$this
->
isSul3Enabled
(
$request
),
'SUL3 is not enabled. Set $wgCentralAuthEnableSul3 to boolean true.'
);
}
/**
* Assert that we're on the shared login domain.
*
* @return void
*/
public
function
assertIsSharedDomain
()
{
Assert
::
precondition
(
$this
->
isSharedDomain
(),
'This action is not allowed because the domain is not the shared login domain.'
);
}
/**
* Assert that we're not on the shared login domain.
*
* @return void
*/
public
function
assertIsNotSharedDomain
()
{
Assert
::
precondition
(
!(
$this
->
isSharedDomain
()
),
'This action is not allowed because the domain is not the shared login domain.'
);
}
/**
* Get the login/signup URL on the shared login domain wiki.
*
* @param string $action 'login' or 'signup' action
* @param WebRequest|null $request There could be more to look at
* in the request like if we're coming from a campaign link.
*
* @return string
*/
public
function
getUrlForSharedDomainAction
(
string
$action
,
?
WebRequest
$request
=
null
):
string
{
switch
(
$action
)
{
case
'login'
:
$localUrl
=
$this
->
titleFactory
->
newFromText
(
'Special:UserLogin'
)->
getLocalURL
();
break
;
case
'signup'
:
$localUrl
=
$this
->
titleFactory
->
newFromText
(
'Special:CreateAccount'
)->
getLocalURL
();
break
;
default
:
throw
new
RuntimeException
(
'Unknown action: '
.
$action
);
}
$url
=
$this
->
config
->
get
(
'CentralAuthSsoUrlPrefix'
)
.
$localUrl
;
if
(
$this
->
mobileContext
&&
$this
->
mobileContext
->
shouldDisplayMobileView
()
)
{
$url
=
wfAppendQuery
(
$url
,
[
'useformat'
=>
'mobile'
]
);
}
else
{
// This is not supposed to happen on the SSO domain but if we're
// in a situation where the shared domain is in mobile view and the
// user is coming from a desktop view, let's inherit that experience
// to the shared domain.
$url
=
wfAppendQuery
(
$url
,
[
'useformat'
=>
'desktop'
]
);
}
return
wfAppendQuery
(
$url
,
[
// At this point, we should just be leaving the local
// wiki before hitting the loginwiki.
'wikiid'
=>
WikiMap
::
getCurrentWikiId
(),
// TODO: Fix T369467
'returnto'
=>
'Main_Page'
,
'usesul3'
=>
'1'
,
'campaign'
=>
$request
?
$request
->
getRawVal
(
'campaign'
)
:
null
,
]
);
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sat, May 16, 19:12 (5 h, 54 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
d9/cd/da14b07ce4b6cc42e4d2c0d24e21
Default Alt Text
SharedDomainUtils.php (6 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment