Completed
Push — master ( e090e4...18d79e )
by Damian
02:26
created

code/EnvironmentChecker.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * Provides an interface for checking the given EnvironmentCheckSuite.
5
 */
6
class EnvironmentChecker extends RequestHandler
7
{
8
    /**
9
     * @var array
10
     */
11
    private static $url_handlers = array(
12
        '' => 'index',
13
    );
14
15
    /**
16
     * @var string
17
     */
18
    protected $checkSuiteName;
19
20
    /**
21
     * @var string
22
     */
23
    protected $title;
24
25
    /**
26
     * @var int
27
     */
28
    protected $errorCode = 500;
29
30
    /**
31
     * @var null|string
32
     */
33
    private static $to_email_address = null;
34
35
    /**
36
     * @var null|string
37
     */
38
    private static $from_email_address = null;
39
40
    /**
41
     * @var bool
42
     */
43
    private static $email_results = false;
44
45
    /**
46
     * @var bool Log results via {@link SS_Log}
47
     */
48
    private static $log_results_warning = false;
49
50
    /**
51
     * @var int Maps to {@link Zend_Log} levels. Defaults to Zend_Log::WARN
52
     */
53
    private static $log_results_warning_level = 4;
54
55
    /**
56
     * @var bool Log results via {@link SS_Log}
57
     */
58
    private static $log_results_error = false;
59
60
    /**
61
     * @var int Maps to {@link Zend_Log} levels. Defaults to Zend_Log::ALERT
62
     */
63
    private static $log_results_error_level = 1;
64
65
    /**
66
     * @param string $checkSuiteName
67
     * @param string $title
68
     */
69
    public function __construct($checkSuiteName, $title)
70
    {
71
        parent::__construct();
72
        
73
        $this->checkSuiteName = $checkSuiteName;
74
        $this->title = $title;
75
    }
76
77
    /**
78
     * @param string $permission
79
     *
80
     * @throws SS_HTTPResponse_Exception
81
     */
82
    public function init($permission = 'ADMIN')
0 ignored issues
show
init uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
83
    {
84
        // if the environment supports it, provide a basic auth challenge and see if it matches configured credentials
85
        if (defined('ENVCHECK_BASICAUTH_USERNAME') && defined('ENVCHECK_BASICAUTH_PASSWORD')) {
86
            if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
87
                // authenticate the input user/pass with the configured credentials
88
                if (
89
                    !(
90
                        $_SERVER['PHP_AUTH_USER'] == ENVCHECK_BASICAUTH_USERNAME
91
                        && $_SERVER['PHP_AUTH_PW'] == ENVCHECK_BASICAUTH_PASSWORD
92
                    )
93
                ) {
94
                    $response = new SS_HTTPResponse(null, 401);
95
                    $response->addHeader('WWW-Authenticate', "Basic realm=\"Environment check\"");
96
                    // Exception is caught by RequestHandler->handleRequest() and will halt further execution
97
                    $e = new SS_HTTPResponse_Exception(null, 401);
98
                    $e->setResponse($response);
99
                    throw $e;
100
                }
101
            } else {
102
                $response = new SS_HTTPResponse(null, 401);
103
                $response->addHeader('WWW-Authenticate', "Basic realm=\"Environment check\"");
104
                // Exception is caught by RequestHandler->handleRequest() and will halt further execution
105
                $e = new SS_HTTPResponse_Exception(null, 401);
106
                $e->setResponse($response);
107
                throw $e;
108
            }
109
        } else {
110
            if (!$this->canAccess(null, $permission)) {
111
                return $this->httpError(403);
112
            }
113
        }
114
    }
115
116
    /**
117
     * @param null|int|Member $member
118
     * @param string $permission
119
     *
120
     * @return bool
121
     *
122
     * @throws SS_HTTPResponse_Exception
123
     */
124
    public function canAccess($member = null, $permission = "ADMIN")
125
    {
126
        if (!$member) {
127
            $member = Member::currentUser();
128
        }
129
130
        if (!$member) {
131
            $member = BasicAuth::requireLogin('Environment Checker', $permission, false);
132
        }
133
134
        // We allow access to this controller regardless of live-status or ADMIN permission only
135
        // if on CLI.  Access to this controller is always allowed in "dev-mode", or of the user is ADMIN.
136
        if (
137
            Director::isDev()
138
            || Director::is_cli()
139
            || empty($permission)
140
            || Permission::checkMember($member, $permission)
141
        ) {
142
            return true;
143
        }
144
145
        // Extended access checks.
146
        // "Veto" style, return NULL to abstain vote.
147
        $canExtended = null;
148
        $results = $this->extend('canAccess', $member);
149
        if ($results && is_array($results)) {
150
            if (!min($results)) {
151
                return false;
152
            } else {
153
                return true;
154
            }
155
        }
156
157
        return false;
158
    }
159
160
    /**
161
     * @return SS_HTTPResponse
162
     */
163
    public function index()
164
    {
165
        $response = new SS_HTTPResponse;
166
        $result = EnvironmentCheckSuite::inst($this->checkSuiteName)->run();
167
168
        if (!$result->ShouldPass()) {
169
            $response->setStatusCode($this->errorCode);
170
        }
171
172
        $resultText = $result->customise(array(
173
            "URL" => Director::absoluteBaseURL(),
174
            "Title" => $this->title,
175
            "Name" => $this->checkSuiteName,
176
            "ErrorCode" => $this->errorCode,
177
        ))->renderWith("EnvironmentChecker");
178
179
        if ($this->config()->email_results && !$result->ShouldPass()) {
180
            $email = new Email($this->config()->from_email_address, $this->config()->to_email_address, $this->title, $resultText);
181
            $email->send();
182
        }
183
184
        // Optionally log errors and warnings individually
185
        foreach ($result->Details() as $detail) {
186
            if ($this->config()->log_results_warning && $detail->StatusCode == EnvironmentCheck::WARNING) {
187
                $this->log(
188
                    sprintf('EnvironmentChecker warning at "%s" check. Message: %s', $detail->Check, $detail->Message),
189
                    $this->config()->log_results_warning_level
190
                );
191
            } elseif ($this->config()->log_results_error && $detail->StatusCode == EnvironmentCheck::ERROR) {
192
                $this->log(
193
                    sprintf('EnvironmentChecker error at "%s" check. Message: %s', $detail->Check, $detail->Message),
194
                    $this->config()->log_results_error_level
195
                );
196
            }
197
        }
198
199
        // output the result as JSON if requested
200
        if (
201
            $this->getRequest()->getExtension() == 'json'
202
            || strpos($this->getRequest()->getHeader('Accept'), 'application/json') !== false
203
        ) {
204
            $response->setBody($result->toJSON());
205
            $response->addHeader('Content-Type', 'application/json');
206
            return $response;
207
        }
208
209
        $response->setBody($resultText);
210
        
211
        return $response;
212
    }
213
214
    /**
215
     * @param string $message
216
     * @param int $level
217
     */
218
    public function log($message, $level)
219
    {
220
        SS_Log::log($message, $level);
221
    }
222
223
    /**
224
     * Set the HTTP status code that should be returned when there's an error.
225
     *
226
     * @param int $errorCode
227
     */
228
    public function setErrorCode($errorCode)
229
    {
230
        $this->errorCode = $errorCode;
231
    }
232
233
    /**
234
     * @deprecated
235
     * @param string $from
236
     */
237
    public static function set_from_email_address($from)
238
    {
239
        Deprecation::notice('2.0', 'Use config API instead');
240
        Config::inst()->update('EnvironmentChecker', 'from_email_address', $from);
241
    }
242
243
    /**
244
     * @deprecated
245
     * @return null|string
246
     */
247
    public static function get_from_email_address()
248
    {
249
        Deprecation::notice('2.0', 'Use config API instead');
250
        return Config::inst()->get('EnvironmentChecker', 'from_email_address');
251
    }
252
253
    /**
254
     * @deprecated
255
     * @param string $to
256
     */
257
    public static function set_to_email_address($to)
258
    {
259
        Deprecation::notice('2.0', 'Use config API instead');
260
        Config::inst()->update('EnvironmentChecker', 'to_email_address',  $to);
261
    }
262
263
    /**
264
     * @deprecated
265
     * @return null|string
266
     */
267
    public static function get_to_email_address()
268
    {
269
        Deprecation::notice('2.0', 'Use config API instead');
270
        return Config::inst()->get('EnvironmentChecker', 'to_email_address');
271
    }
272
273
    /**
274
     * @deprecated
275
     * @param bool $results
276
     */
277
    public static function set_email_results($results)
278
    {
279
        Deprecation::notice('2.0', 'Use config API instead');
280
        Config::inst()->update('EnvironmentChecker', 'email_results', $results);
281
    }
282
283
    /**
284
     * @deprecated
285
     * @return bool
286
     */
287
    public static function get_email_results()
288
    {
289
        Deprecation::notice('2.0', 'Use config API instead');
290
        return Config::inst()->get('EnvironmentChecker', 'email_results');
291
    }
292
}
293