Issues (2882)

src/Security/CMSSecurity.php (5 issues)

1
<?php
2
3
namespace SilverStripe\Security;
4
5
use SilverStripe\Admin\AdminRootController;
0 ignored issues
show
The type SilverStripe\Admin\AdminRootController was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SilverStripe\Admin\LeftAndMain;
0 ignored issues
show
The type SilverStripe\Admin\LeftAndMain was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use SilverStripe\Control\Controller;
8
use SilverStripe\Control\Director;
9
use SilverStripe\Control\HTTPResponse;
10
use SilverStripe\Core\Convert;
11
use SilverStripe\Core\Manifest\ModuleLoader;
12
use SilverStripe\ORM\FieldType\DBField;
13
use SilverStripe\ORM\FieldType\DBHTMLText;
14
use SilverStripe\View\Requirements;
15
use SilverStripe\View\SSViewer;
16
17
/**
18
 * Provides a security interface functionality within the cms
19
 */
20
class CMSSecurity extends Security
21
{
22
    private static $allowed_actions = array(
0 ignored issues
show
The private property $allowed_actions is not used, and could be removed.
Loading history...
23
        'login',
24
        'success'
25
    );
26
27
    /**
28
     * Enable in-cms reauthentication
29
     *
30
     * @var boolean
31
     * @config
32
     */
33
    private static $reauth_enabled = true;
0 ignored issues
show
The private property $reauth_enabled is not used, and could be removed.
Loading history...
34
35
    protected function init()
36
    {
37
        parent::init();
38
39
        // Assign default cms theme and replace user-specified themes
40
        SSViewer::set_themes(LeftAndMain::config()->uninherited('admin_themes'));
41
42
        if (ModuleLoader::getModule('silverstripe/admin')) {
43
            // Core styles / vendor scripts
44
            Requirements::javascript('silverstripe/admin: client/dist/js/vendor.js');
45
            Requirements::css('silverstripe/admin: client/dist/styles/bundle.css');
46
        }
47
    }
48
49
    public function login($request = null, $service = Authenticator::CMS_LOGIN)
50
    {
51
        return parent::login($request, Authenticator::CMS_LOGIN);
52
    }
53
54
    public function Link($action = null)
55
    {
56
        /** @skipUpgrade */
57
        return Controller::join_links(Director::baseURL(), "CMSSecurity", $action);
58
    }
59
60
    protected function getAuthenticator($name = 'cms')
61
    {
62
        return parent::getAuthenticator($name);
63
    }
64
65
    public function getApplicableAuthenticators($service = Authenticator::CMS_LOGIN)
66
    {
67
        return parent::getApplicableAuthenticators($service);
68
    }
69
70
    /**
71
     * Get known logged out member
72
     *
73
     * @return Member
74
     */
75
    public function getTargetMember()
76
    {
77
        $tempid = $this->getRequest()->requestVar('tempid');
78
        if ($tempid) {
79
            return Member::member_from_tempid($tempid);
80
        }
81
82
        return null;
83
    }
84
85
    public function getResponseController($title)
86
    {
87
        // Use $this to prevent use of Page to render underlying templates
88
        return $this;
89
    }
90
91
    protected function getSessionMessage(&$messageType = null)
92
    {
93
        $message =  parent::getSessionMessage($messageType);
94
        if ($message) {
95
            return $message;
96
        }
97
98
        // Format
99
        return _t(
100
            __CLASS__ . '.LOGIN_MESSAGE',
101
            '<p>Your session has timed out due to inactivity</p>'
102
        );
103
    }
104
105
    /**
106
     * Check if there is a logged in member
107
     *
108
     * @return bool
109
     */
110
    public function getIsloggedIn()
111
    {
112
        return !!Security::getCurrentUser();
113
    }
114
115
    /**
116
     * Redirects the user to the external login page
117
     *
118
     * @return HTTPResponse
119
     */
120
    protected function redirectToExternalLogin()
121
    {
122
        $loginURL = Security::create()->Link('login');
123
        $loginURLATT = Convert::raw2att($loginURL);
124
        $loginURLJS = Convert::raw2js($loginURL);
125
        $message = _t(
126
            __CLASS__ . '.INVALIDUSER',
127
            '<p>Invalid user. <a target="_top" href="{link}">Please re-authenticate here</a> to continue.</p>',
128
            'Message displayed to user if their session cannot be restored',
129
            array('link' => $loginURLATT)
130
        );
131
        $response = $this->getResponse();
132
        $response->setStatusCode(200);
133
        $response->setBody(<<<PHP
134
<!DOCTYPE html>
135
<html><body>
136
$message
137
<script type="application/javascript">
138
setTimeout(function(){top.location.href = "$loginURLJS";}, 0);
139
</script>
140
</body></html>
141
PHP
142
        );
143
        $this->setResponse($response);
144
145
        return $response;
146
    }
147
148
    protected function preLogin()
149
    {
150
        // If no member has been previously logged in for this session, force a redirect to the main login page
151
        if (!$this->getTargetMember()) {
152
            return $this->redirectToExternalLogin();
153
        }
154
155
        return parent::preLogin();
156
    }
157
158
    /**
159
     * Determine if CMSSecurity is enabled
160
     *
161
     * @return bool
162
     */
163
    public function enabled()
164
    {
165
        // Disable shortcut
166
        if (!static::config()->get('reauth_enabled')) {
167
            return false;
168
        }
169
170
        return count($this->getApplicableAuthenticators(Authenticator::CMS_LOGIN)) > 0;
171
    }
172
173
    /**
174
     * Given a successful login, tell the parent frame to close the dialog
175
     *
176
     * @return HTTPResponse|DBField
177
     */
178
    public function success()
179
    {
180
        // Ensure member is properly logged in
181
        if (!Security::getCurrentUser() || !class_exists(AdminRootController::class)) {
182
            return $this->redirectToExternalLogin();
183
        }
184
185
        // Get redirect url
186
        $controller = $this->getResponseController(_t(__CLASS__ . '.SUCCESS', 'Success'));
187
        $backURLs = array(
188
            $this->getRequest()->requestVar('BackURL'),
189
            $this->getRequest()->getSession()->get('BackURL'),
190
            Director::absoluteURL(AdminRootController::config()->get('url_base'), true),
0 ignored issues
show
true of type true is incompatible with the type string expected by parameter $relativeParent of SilverStripe\Control\Director::absoluteURL(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

190
            Director::absoluteURL(AdminRootController::config()->get('url_base'), /** @scrutinizer ignore-type */ true),
Loading history...
191
        );
192
        $backURL = null;
193
        foreach ($backURLs as $backURL) {
194
            if ($backURL && Director::is_site_url($backURL)) {
195
                break;
196
            }
197
        }
198
199
        // Show login
200
        $controller = $controller->customise(array(
201
            'Content' => DBField::create_field(DBHTMLText::class, _t(
202
                __CLASS__ . '.SUCCESSCONTENT',
203
                '<p>Login success. If you are not automatically redirected '
204
                . '<a target="_top" href="{link}">click here</a></p>',
205
                'Login message displayed in the cms popup once a user has re-authenticated themselves',
206
                array('link' => Convert::raw2att($backURL))
207
            ))
208
        ));
209
210
        return $controller->renderWith($this->getTemplatesFor('success'));
211
    }
212
}
213