Skip to content

Commit f29103d

Browse files
committed
Merge branch 'master' into develop
2 parents b827dc2 + 2cf5152 commit f29103d

File tree

6 files changed

+585
-1
lines changed

6 files changed

+585
-1
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
/**
3+
* Timestamp Log File Writer
4+
*
5+
* Use this custom log writer to output log messages
6+
* to a daily, weekly, monthly, or yearly log file. Log
7+
* files will inherently rotate based on the specified
8+
* log file name format and the current time.
9+
*
10+
* USAGE
11+
*
12+
* $app = new Slim(array(
13+
* 'log.writer' => new TimestampLogFileWriter()
14+
* ));
15+
*
16+
* SETTINGS
17+
*
18+
* You may customize this log writer by passing an array of
19+
* settings into the class constructor. Available options
20+
* are shown above the constructor method below.
21+
*
22+
* @author Josh Lockhart <[email protected]>
23+
* @copyright 2012 Josh Lockhart
24+
*
25+
* MIT LICENSE
26+
*
27+
* Permission is hereby granted, free of charge, to any person obtaining
28+
* a copy of this software and associated documentation files (the
29+
* "Software"), to deal in the Software without restriction, including
30+
* without limitation the rights to use, copy, modify, merge, publish,
31+
* distribute, sublicense, and/or sell copies of the Software, and to
32+
* permit persons to whom the Software is furnished to do so, subject to
33+
* the following conditions:
34+
*
35+
* The above copyright notice and this permission notice shall be
36+
* included in all copies or substantial portions of the Software.
37+
*
38+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
39+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
40+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
41+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
42+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
43+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
44+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
45+
*/
46+
class TimestampLogFileWriter {
47+
/**
48+
* @var resource
49+
*/
50+
protected $resource;
51+
52+
/**
53+
* @var array
54+
*/
55+
protected $settings;
56+
57+
/**
58+
* Constructor
59+
*
60+
* Prepare this log writer. Available settings are:
61+
*
62+
* path:
63+
* (string) The relative or absolute filesystem path to a writable directory.
64+
*
65+
* name_format:
66+
* (string) The log file name format; parsed with `date()`.
67+
*
68+
* message_format:
69+
* (string) The log message format; available tokens are...
70+
* %label% Replaced with the log message level (e.g. FATAL, ERROR, WARN).
71+
* %date% Replaced with a ISO8601 date string for current timezone.
72+
* %message% Replaced with the log message, coerced to a string.
73+
*
74+
* @param array $settings
75+
* @return void
76+
*/
77+
public function __construct( $settings = array() ) {
78+
//Merge user settings
79+
$this->settings = array_merge(array(
80+
'path' => './logs',
81+
'name_format' => 'Y-m-d',
82+
'message_format' => '%label% - %date% - %message%'
83+
), $settings);
84+
85+
//Remove trailing slash from log path
86+
$this->settings['path'] = rtrim($this->settings['path'], DIRECTORY_SEPARATOR);
87+
}
88+
89+
/**
90+
* Write to log
91+
*
92+
* @param mixed $object
93+
* @param int $level
94+
* @return void
95+
*/
96+
public function write( $object, $level ) {
97+
//Determine label
98+
$label = 'DEBUG';
99+
switch ( $level ) {
100+
case 0:
101+
$label = 'FATAL';
102+
break;
103+
case 1:
104+
$label = 'ERROR';
105+
break;
106+
case 2:
107+
$label = 'WARN';
108+
break;
109+
case 3:
110+
$label = 'INFO';
111+
break;
112+
}
113+
114+
//Get formatted log message
115+
$message = str_replace(array(
116+
'%label%',
117+
'%date%',
118+
'%message%'
119+
), array(
120+
$label,
121+
date('c'),
122+
(string)$object
123+
), $this->settings['message_format']);
124+
125+
//Open resource handle to log file
126+
if (! $this->resource) {
127+
$this->resource = fopen($this->settings['path'] . DIRECTORY_SEPARATOR . date($this->settings['name_format']), 'a');
128+
}
129+
130+
//Output to resource
131+
fwrite($this->resource, $message . PHP_EOL);
132+
}
133+
}

Middleware/CsrfGuard.php

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
/**
4+
* CsrfGuard
5+
*
6+
* This middleware provides protection from CSRF attacks
7+
* USAGE
8+
*
9+
* // Adding middleware
10+
* $app = new Slim();
11+
* $app->add(new CsrfGuard());
12+
*
13+
* // Setting token in view
14+
* <input type="hidden" name="<?=$csrf_key?>" value="<?=$csrf_token?>">
15+
*
16+
* @author Mikhail Osher, https://github.com/miraage
17+
* @version 1.0
18+
*/
19+
class CsrfGuard extends Slim_Middleware {
20+
/**
21+
* Request key
22+
*
23+
* @var string
24+
*/
25+
protected $key;
26+
27+
/**
28+
* Constructor
29+
*
30+
* @param string $key Request key
31+
*/
32+
public function __construct( $key = 'csrf_token' ) {
33+
// Validate key (i won't use htmlspecialchars)
34+
if ( !is_string($key) || empty($key) || preg_match('/[^a-zA-Z0-9\-\_]/', $key) ) {
35+
throw new OutOfBoundsException('Invalid key' . $key);
36+
}
37+
38+
$this->key = $key;
39+
}
40+
41+
/**
42+
* Call middleware
43+
*/
44+
public function call() {
45+
// Attach as hook
46+
$this->app->hook('slim.before', array($this, 'check'));
47+
48+
// Call next middleware
49+
$this->next->call();
50+
}
51+
52+
/**
53+
* Check token
54+
*/
55+
public function check() {
56+
// Create token
57+
if ( session_id() !== "" ){
58+
if ( ! isset( $_SESSION[ $this->key ] ) ){
59+
$_SESSION[ $this->key ] = sha1( serialize( $_SERVER ) . rand( 0, 0xffffffff ) );
60+
}
61+
} else {
62+
throw new Exception( "Session are required to use CSRF Guard" );
63+
}
64+
$token = $_SESSION[ $this->key ];
65+
66+
// Validate
67+
if ( in_array($this->app->request()->getMethod(), array('POST', 'PUT', 'DELETE')) ) {
68+
$usertoken = $this->app->request()->post($this->key);
69+
if ( $token !== $usertoken ) {
70+
$this->app->halt(400, 'Missing token');
71+
}
72+
}
73+
74+
// Assign to view
75+
$this->app->view()->appendData(array(
76+
'csrf_key' => $this->key,
77+
'csrf_token' => $token,
78+
));
79+
}
80+
}

Middleware/HttpBasicAuth.php

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
/**
3+
* HTTP Basic Authentication
4+
*
5+
* Use this middleware with your Slim Framework application
6+
* to require HTTP basic auth for all routes.
7+
*
8+
* @author Josh Lockhart <[email protected]>
9+
* @version 1.0
10+
* @copyright 2012 Josh Lockhart
11+
*
12+
* USAGE
13+
*
14+
* $app = new Slim();
15+
* $app->add(new HttpBasicAuth('theUsername', 'thePassword'));
16+
*
17+
* MIT LICENSE
18+
*
19+
* Permission is hereby granted, free of charge, to any person obtaining
20+
* a copy of this software and associated documentation files (the
21+
* "Software"), to deal in the Software without restriction, including
22+
* without limitation the rights to use, copy, modify, merge, publish,
23+
* distribute, sublicense, and/or sell copies of the Software, and to
24+
* permit persons to whom the Software is furnished to do so, subject to
25+
* the following conditions:
26+
*
27+
* The above copyright notice and this permission notice shall be
28+
* included in all copies or substantial portions of the Software.
29+
*
30+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
31+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
32+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
33+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
34+
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35+
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36+
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37+
*/
38+
class HttpBasicAuth extends Slim_Middleware {
39+
/**
40+
* @var string
41+
*/
42+
protected $realm;
43+
44+
/**
45+
* @var string
46+
*/
47+
protected $username;
48+
49+
/**
50+
* @var string
51+
*/
52+
protected $password;
53+
54+
/**
55+
* Constructor
56+
*
57+
* @param string $username The HTTP Authentication username
58+
* @param string $password The HTTP Authentication password
59+
* @param string $realm The HTTP Authentication realm
60+
* @return void
61+
*/
62+
public function __construct( $username, $password, $realm = 'Protected Area' ) {
63+
$this->username = $username;
64+
$this->password = $password;
65+
$this->realm = $realm;
66+
}
67+
68+
/**
69+
* Call
70+
*
71+
* This method will check the HTTP request headers for previous authentication. If
72+
* the request has already authenticated, the next middleware is called. Otherwise,
73+
* a 401 Authentication Required response is returned to the client.
74+
*
75+
* @return void
76+
*/
77+
public function call() {
78+
$req = $this->app->request();
79+
$res = $this->app->response();
80+
$authUser = $req->headers('PHP_AUTH_USER');
81+
$authPass = $req->headers('PHP_AUTH_PW');
82+
if ( $authUser && $authPass && $authUser === $this->username && $authPass === $this->password ) {
83+
$this->next->call();
84+
} else {
85+
$res->status(401);
86+
$res->header('WWW-Authenticate', sprintf('Basic realm="%s"', $this->realm));
87+
}
88+
}
89+
}

0 commit comments

Comments
 (0)