Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
37.50% covered (danger)
37.50%
12 / 32
16.67% covered (danger)
16.67%
1 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
SharedDomainUtils
37.50% covered (danger)
37.50%
12 / 32
16.67% covered (danger)
16.67%
1 / 6
40.54
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 isSharedDomain
83.33% covered (warning)
83.33%
10 / 12
0.00% covered (danger)
0.00%
0 / 1
4.07
 isSul3Enabled
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
12
 assertSul3Enabled
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 assertIsSharedDomain
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 assertIsNotSharedDomain
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Extension\CentralAuth;
4
5use MediaWiki\Config\Config;
6use MediaWiki\Request\WebRequest;
7use MediaWiki\Utils\UrlUtils;
8use Wikimedia\Assert\Assert;
9
10/**
11 * Utilities for handling the shared domain name used for SUL3 login.
12 * This class is kept lightweight, so it can be used in early hooks.
13 */
14class SharedDomainUtils {
15
16    private Config $config;
17    private UrlUtils $urlUtils;
18
19    private bool $isSharedDomain;
20
21    public function __construct(
22        Config $config,
23        UrlUtils $urlUtils
24    ) {
25        $this->config = $config;
26        $this->urlUtils = $urlUtils;
27    }
28
29    /**
30     * Check if the current domain is the shared domain used for SUL3 login
31     * (i.e. the domain in $CentralAuthSsoUrlPrefix). Assumes that $wgCanonicalServer
32     * is set to the shared domain when the wiki is accessed via that domain.
33     * @return bool
34     */
35    public function isSharedDomain(): bool {
36        // @phan-suppress-next-line PhanRedundantCondition
37        if ( isset( $this->isSharedDomain ) ) {
38            return $this->isSharedDomain;
39        }
40
41        $centralAuthSsoUrlPrefix = $this->config->get( 'CentralAuthSsoUrlPrefix' );
42        if ( !$centralAuthSsoUrlPrefix ) {
43            $this->isSharedDomain = false;
44            return $this->isSharedDomain;
45        }
46        $sharedDomain = $this->urlUtils->parse( $centralAuthSsoUrlPrefix )['host'] ?? null;
47        $currentDomain = $this->urlUtils->parse(
48            $this->urlUtils->getServer( PROTO_CANONICAL ) ?? ''
49        )['host'] ?? null;
50        $this->isSharedDomain = $sharedDomain && $currentDomain === $sharedDomain;
51        return $this->isSharedDomain;
52    }
53
54    /**
55     * Detects if we're in SUL3 mode. Returns true if that is the case
56     * and false otherwise.
57     *
58     * @param WebRequest $request
59     *
60     * @return bool
61     */
62    public function isSul3Enabled( WebRequest $request ): bool {
63        $configFlag = $this->config->get( 'CentralAuthEnableSul3' );
64        if ( $configFlag === 'always' ) {
65            return true;
66        } elseif ( $configFlag === 'query-flag' ) {
67            return $request->getCheck( 'usesul3' );
68        } else {
69            return false;
70        }
71    }
72
73    /**
74     * Assert that the SUL3 mode is set.
75     *
76     * @param WebRequest $request
77     *
78     * @return void
79     */
80    public function assertSul3Enabled( WebRequest $request ) {
81        Assert::precondition(
82            $this->isSul3Enabled( $request ),
83            'SUL3 is not enabled. Set $wgCentralAuthEnableSul3 to boolean true.'
84        );
85    }
86
87    /**
88     * Assert that we're on the shared login domain.
89     * @return void
90     */
91    public function assertIsSharedDomain() {
92        Assert::precondition(
93            $this->isSharedDomain(),
94            'This action is not allowed because the domain is not the shared login domain.'
95        );
96    }
97
98    /**
99     * Assert that we're not on the shared login domain.
100     *
101     * @return void
102     */
103    public function assertIsNotSharedDomain() {
104        Assert::precondition(
105            !( $this->isSharedDomain() ),
106            'This action is not allowed because the domain is not the shared login domain.'
107        );
108    }
109
110}