Completed
Push — master ( cc70b5...764c78 )
by Robbie
01:40
created
tests/CookieStoreTest.php 1 patch
Indentation   +55 added lines, -55 removed lines patch added patch discarded remove patch
@@ -10,69 +10,69 @@
 block discarded – undo
10 10
 
11 11
 class CookieStoreTest extends AbstractTest
12 12
 {
13
-    protected function getStore()
14
-    {
15
-        $store = Injector::inst()->get(CookieStore::class);
16
-        $store->setKey(uniqid());
17
-        $store->open(TempFolder::getTempFolder(BASE_PATH).'/'.__CLASS__, 'SESSIONCOOKIE');
13
+	protected function getStore()
14
+	{
15
+		$store = Injector::inst()->get(CookieStore::class);
16
+		$store->setKey(uniqid());
17
+		$store->open(TempFolder::getTempFolder(BASE_PATH).'/'.__CLASS__, 'SESSIONCOOKIE');
18 18
 
19
-        return $store;
20
-    }
19
+		return $store;
20
+	}
21 21
 
22
-    public function testStoreLargeData()
23
-    {
24
-        $session = uniqid();
25
-        $store = $this->getStore();
22
+	public function testStoreLargeData()
23
+	{
24
+		$session = uniqid();
25
+		$store = $this->getStore();
26 26
 
27
-        // Test new session is blank
28
-        $result = $store->read($session);
29
-        $this->assertEmpty($result);
27
+		// Test new session is blank
28
+		$result = $store->read($session);
29
+		$this->assertEmpty($result);
30 30
 
31
-        // Save data against session
32
-        $data1 = array(
33
-            'Large' => str_repeat('A', 600),
34
-            'Content' => str_repeat('B', 600)
35
-        );
36
-        $store->write($session, serialize($data1));
37
-        $result = $store->read($session);
31
+		// Save data against session
32
+		$data1 = array(
33
+			'Large' => str_repeat('A', 600),
34
+			'Content' => str_repeat('B', 600)
35
+		);
36
+		$store->write($session, serialize($data1));
37
+		$result = $store->read($session);
38 38
 
39
-        // Cookies should not try to store data that large
40
-        $this->assertEmpty($result);
41
-    }
39
+		// Cookies should not try to store data that large
40
+		$this->assertEmpty($result);
41
+	}
42 42
 
43
-    /**
44
-     * Ensure that subsequent reads without the necessary write do not report data
45
-     */
46
-    public function testReadInvalidatesData()
47
-    {
48
-        $session = uniqid();
49
-        $store = $this->getStore();
43
+	/**
44
+	 * Ensure that subsequent reads without the necessary write do not report data
45
+	 */
46
+	public function testReadInvalidatesData()
47
+	{
48
+		$session = uniqid();
49
+		$store = $this->getStore();
50 50
 
51
-        // Test new session is blank
52
-        $result = $store->read($session);
53
-        $this->assertEmpty($result);
51
+		// Test new session is blank
52
+		$result = $store->read($session);
53
+		$this->assertEmpty($result);
54 54
 
55
-        // Save data against session
56
-        $data1 = array(
57
-            'Color' => 'red',
58
-            'Animal' => 'elephant'
59
-        );
60
-        $store->write($session, serialize($data1));
61
-        $result = $store->read($session);
62
-        $this->assertEquals($data1, unserialize($result));
55
+		// Save data against session
56
+		$data1 = array(
57
+			'Color' => 'red',
58
+			'Animal' => 'elephant'
59
+		);
60
+		$store->write($session, serialize($data1));
61
+		$result = $store->read($session);
62
+		$this->assertEquals($data1, unserialize($result));
63 63
 
64
-        // Since we have read the data into the result, the application could modify this content
65
-        // and be unable to write it back due to headers being sent. We should thus assume
66
-        // that subsequent reads without a successful write do not purport to have valid data
67
-        $data1['Color'] = 'blue';
68
-        $result = $store->read($session);
69
-        $this->assertEmpty($result);
64
+		// Since we have read the data into the result, the application could modify this content
65
+		// and be unable to write it back due to headers being sent. We should thus assume
66
+		// that subsequent reads without a successful write do not purport to have valid data
67
+		$data1['Color'] = 'blue';
68
+		$result = $store->read($session);
69
+		$this->assertEmpty($result);
70 70
 
71
-        // Check that writing to cookie fails after headers are sent and these results remain
72
-        // invalidated
73
-        TestCookieStore::$override_headers_sent = true;
74
-        $store->write($session, serialize($data1));
75
-        $result = $store->read($session);
76
-        $this->assertEmpty($result);
77
-    }
71
+		// Check that writing to cookie fails after headers are sent and these results remain
72
+		// invalidated
73
+		TestCookieStore::$override_headers_sent = true;
74
+		$store->write($session, serialize($data1));
75
+		$result = $store->read($session);
76
+		$this->assertEmpty($result);
77
+	}
78 78
 }
Please login to merge, or discard this patch.
src/Crypto/McryptCrypto.php 2 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -87,7 +87,7 @@
 block discarded – undo
87 87
      *
88 88
      * @param $data - The encrypted-and-signed message as base64 ASCII
89 89
      *
90
-     * @return bool|string - The decrypted cleartext or false if signature failed
90
+     * @return string|false - The decrypted cleartext or false if signature failed
91 91
      */
92 92
     public function decrypt($data)
93 93
     {
Please login to merge, or discard this patch.
Indentation   +105 added lines, -105 removed lines patch added patch discarded remove patch
@@ -8,109 +8,109 @@
 block discarded – undo
8 8
  */
9 9
 class McryptCrypto implements CryptoHandler
10 10
 {
11
-    protected $key;
12
-
13
-    protected $ivSize;
14
-
15
-    protected $keySize;
16
-
17
-    protected $salt;
18
-
19
-    protected $saltedKey;
20
-
21
-    /**
22
-     * @return string
23
-     */
24
-    public function getKey()
25
-    {
26
-        return $this->key;
27
-    }
28
-
29
-    /**
30
-     * @return string
31
-     */
32
-    public function getSalt()
33
-    {
34
-        return $this->salt;
35
-    }
36
-
37
-    /**
38
-     * @param $key a per-site secret string which is used as the base encryption key.
39
-     * @param $salt a per-session random string which is used as a salt to generate a per-session key
40
-     *
41
-     * The base encryption key needs to stay secret. If an attacker ever gets it, they can read their session,
42
-     * and even modify & re-sign it.
43
-     *
44
-     * The salt is a random per-session string that is used with the base encryption key to create a per-session key.
45
-     * This (amongst other things) makes sure an attacker can't use a known-plaintext attack to guess the key.
46
-     *
47
-     * Normally we could create a salt on encryption, send it to the client as part of the session (it doesn't
48
-     * need to remain secret), then use the returned salt to decrypt. But we already have the Session ID which makes
49
-     * a great salt, so no need to generate & handle another one.
50
-     */
51
-    public function __construct($key, $salt)
52
-    {
53
-        $this->ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
54
-        $this->keySize = mcrypt_get_key_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
55
-
56
-        $this->key = $key;
57
-        $this->salt = $salt;
58
-        $this->saltedKey = hash_pbkdf2('sha256', $this->key, $this->salt, 1000, $this->keySize, true);
59
-    }
60
-
61
-    /**
62
-     * Encrypt and then sign some cleartext
63
-     *
64
-     * @param $cleartext - The cleartext to encrypt and sign
65
-     * @return string - The encrypted-and-signed message as base64 ASCII.
66
-     */
67
-    public function encrypt($cleartext)
68
-    {
69
-        $iv = mcrypt_create_iv($this->ivSize, MCRYPT_DEV_URANDOM);
70
-
71
-        $enc = mcrypt_encrypt(
72
-            MCRYPT_RIJNDAEL_256,
73
-            $this->saltedKey,
74
-            $cleartext,
75
-            MCRYPT_MODE_CBC,
76
-            $iv
77
-        );
78
-
79
-        $hash = hash_hmac('sha256', $enc, $this->saltedKey);
80
-
81
-        return base64_encode($iv.$hash.$enc);
82
-    }
83
-
84
-    /**
85
-     * Check the signature on an encrypted-and-signed message, and if valid
86
-     * decrypt the content
87
-     *
88
-     * @param $data - The encrypted-and-signed message as base64 ASCII
89
-     *
90
-     * @return bool|string - The decrypted cleartext or false if signature failed
91
-     */
92
-    public function decrypt($data)
93
-    {
94
-        $data = base64_decode($data);
95
-
96
-        $iv   = substr($data, 0, $this->ivSize);
97
-        $hash = substr($data, $this->ivSize, 64);
98
-        $enc  = substr($data, $this->ivSize + 64);
99
-
100
-        $cleartext = rtrim(mcrypt_decrypt(
101
-            MCRYPT_RIJNDAEL_256,
102
-            $this->saltedKey,
103
-            $enc,
104
-            MCRYPT_MODE_CBC,
105
-            $iv
106
-        ), "\x00");
107
-
108
-        // Needs to be after decrypt so it always runs, to avoid timing attack
109
-        $gen_hash = hash_hmac('sha256', $enc, $this->saltedKey);
110
-
111
-        if ($gen_hash == $hash) {
112
-            return $cleartext;
113
-        }
114
-        return false;
115
-    }
11
+	protected $key;
12
+
13
+	protected $ivSize;
14
+
15
+	protected $keySize;
16
+
17
+	protected $salt;
18
+
19
+	protected $saltedKey;
20
+
21
+	/**
22
+	 * @return string
23
+	 */
24
+	public function getKey()
25
+	{
26
+		return $this->key;
27
+	}
28
+
29
+	/**
30
+	 * @return string
31
+	 */
32
+	public function getSalt()
33
+	{
34
+		return $this->salt;
35
+	}
36
+
37
+	/**
38
+	 * @param $key a per-site secret string which is used as the base encryption key.
39
+	 * @param $salt a per-session random string which is used as a salt to generate a per-session key
40
+	 *
41
+	 * The base encryption key needs to stay secret. If an attacker ever gets it, they can read their session,
42
+	 * and even modify & re-sign it.
43
+	 *
44
+	 * The salt is a random per-session string that is used with the base encryption key to create a per-session key.
45
+	 * This (amongst other things) makes sure an attacker can't use a known-plaintext attack to guess the key.
46
+	 *
47
+	 * Normally we could create a salt on encryption, send it to the client as part of the session (it doesn't
48
+	 * need to remain secret), then use the returned salt to decrypt. But we already have the Session ID which makes
49
+	 * a great salt, so no need to generate & handle another one.
50
+	 */
51
+	public function __construct($key, $salt)
52
+	{
53
+		$this->ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
54
+		$this->keySize = mcrypt_get_key_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
55
+
56
+		$this->key = $key;
57
+		$this->salt = $salt;
58
+		$this->saltedKey = hash_pbkdf2('sha256', $this->key, $this->salt, 1000, $this->keySize, true);
59
+	}
60
+
61
+	/**
62
+	 * Encrypt and then sign some cleartext
63
+	 *
64
+	 * @param $cleartext - The cleartext to encrypt and sign
65
+	 * @return string - The encrypted-and-signed message as base64 ASCII.
66
+	 */
67
+	public function encrypt($cleartext)
68
+	{
69
+		$iv = mcrypt_create_iv($this->ivSize, MCRYPT_DEV_URANDOM);
70
+
71
+		$enc = mcrypt_encrypt(
72
+			MCRYPT_RIJNDAEL_256,
73
+			$this->saltedKey,
74
+			$cleartext,
75
+			MCRYPT_MODE_CBC,
76
+			$iv
77
+		);
78
+
79
+		$hash = hash_hmac('sha256', $enc, $this->saltedKey);
80
+
81
+		return base64_encode($iv.$hash.$enc);
82
+	}
83
+
84
+	/**
85
+	 * Check the signature on an encrypted-and-signed message, and if valid
86
+	 * decrypt the content
87
+	 *
88
+	 * @param $data - The encrypted-and-signed message as base64 ASCII
89
+	 *
90
+	 * @return bool|string - The decrypted cleartext or false if signature failed
91
+	 */
92
+	public function decrypt($data)
93
+	{
94
+		$data = base64_decode($data);
95
+
96
+		$iv   = substr($data, 0, $this->ivSize);
97
+		$hash = substr($data, $this->ivSize, 64);
98
+		$enc  = substr($data, $this->ivSize + 64);
99
+
100
+		$cleartext = rtrim(mcrypt_decrypt(
101
+			MCRYPT_RIJNDAEL_256,
102
+			$this->saltedKey,
103
+			$enc,
104
+			MCRYPT_MODE_CBC,
105
+			$iv
106
+		), "\x00");
107
+
108
+		// Needs to be after decrypt so it always runs, to avoid timing attack
109
+		$gen_hash = hash_hmac('sha256', $enc, $this->saltedKey);
110
+
111
+		if ($gen_hash == $hash) {
112
+			return $cleartext;
113
+		}
114
+		return false;
115
+	}
116 116
 }
Please login to merge, or discard this patch.
src/Crypto/OpenSSLCrypto.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -75,7 +75,7 @@
 block discarded – undo
75 75
      *
76 76
      * @param string $data - The encrypted-and-signed message as base64 ASCII
77 77
      *
78
-     * @return bool|string - The decrypted cleartext or false if signature failed
78
+     * @return string|false - The decrypted cleartext or false if signature failed
79 79
      */
80 80
     public function decrypt($data)
81 81
     {
Please login to merge, or discard this patch.
Indentation   +76 added lines, -76 removed lines patch added patch discarded remove patch
@@ -8,90 +8,90 @@
 block discarded – undo
8 8
  */
9 9
 class OpenSSLCrypto implements CryptoHandler
10 10
 {
11
-    protected $key;
11
+	protected $key;
12 12
 
13
-    protected $salt;
13
+	protected $salt;
14 14
 
15
-    protected $saltedKey;
15
+	protected $saltedKey;
16 16
 
17
-    /**
18
-     * @return string
19
-     */
20
-    public function getKey()
21
-    {
22
-        return $this->key;
23
-    }
17
+	/**
18
+	 * @return string
19
+	 */
20
+	public function getKey()
21
+	{
22
+		return $this->key;
23
+	}
24 24
 
25
-    /**
26
-     * @return string
27
-     */
28
-    public function getSalt()
29
-    {
30
-        return $this->salt;
31
-    }
25
+	/**
26
+	 * @return string
27
+	 */
28
+	public function getSalt()
29
+	{
30
+		return $this->salt;
31
+	}
32 32
 
33
-    /**
34
-     * @param string $key a per-site secret string which is used as the base encryption key.
35
-     * @param string $salt a per-session random string which is used as a salt to generate a per-session key
36
-     *
37
-     * The base encryption key needs to stay secret. If an attacker ever gets it, they can read their session,
38
-     * and even modify & re-sign it.
39
-     *
40
-     * The salt is a random per-session string that is used with the base encryption key to create a per-session key.
41
-     * This (amongst other things) makes sure an attacker can't use a known-plaintext attack to guess the key.
42
-     *
43
-     * Normally we could create a salt on encryption, send it to the client as part of the session (it doesn't
44
-     * need to remain secret), then use the returned salt to decrypt. But we already have the Session ID which makes
45
-     * a great salt, so no need to generate & handle another one.
46
-     */
47
-    public function __construct($key, $salt)
48
-    {
49
-        $this->key = $key;
50
-        $this->salt = $salt;
51
-        $this->saltedKey = hash_pbkdf2('sha256', $this->key, $this->salt, 1000, 0, true);
52
-    }
33
+	/**
34
+	 * @param string $key a per-site secret string which is used as the base encryption key.
35
+	 * @param string $salt a per-session random string which is used as a salt to generate a per-session key
36
+	 *
37
+	 * The base encryption key needs to stay secret. If an attacker ever gets it, they can read their session,
38
+	 * and even modify & re-sign it.
39
+	 *
40
+	 * The salt is a random per-session string that is used with the base encryption key to create a per-session key.
41
+	 * This (amongst other things) makes sure an attacker can't use a known-plaintext attack to guess the key.
42
+	 *
43
+	 * Normally we could create a salt on encryption, send it to the client as part of the session (it doesn't
44
+	 * need to remain secret), then use the returned salt to decrypt. But we already have the Session ID which makes
45
+	 * a great salt, so no need to generate & handle another one.
46
+	 */
47
+	public function __construct($key, $salt)
48
+	{
49
+		$this->key = $key;
50
+		$this->salt = $salt;
51
+		$this->saltedKey = hash_pbkdf2('sha256', $this->key, $this->salt, 1000, 0, true);
52
+	}
53 53
 
54
-    /**
55
-     * Encrypt and then sign some cleartext
56
-     *
57
-     * @param string $cleartext - The cleartext to encrypt and sign
58
-     * @return string - The encrypted-and-signed message as base64 ASCII.
59
-     */
60
-    public function encrypt($cleartext)
61
-    {
62
-        $cipher = "AES-256-CBC";
63
-        $ivlen = openssl_cipher_iv_length($cipher);
64
-        $iv = openssl_random_pseudo_bytes($ivlen);
65
-        $ciphertext_raw = openssl_encrypt($cleartext, $cipher, $this->saltedKey, $options = OPENSSL_RAW_DATA, $iv);
66
-        $hmac = hash_hmac('sha256', $ciphertext_raw, $this->saltedKey, $as_binary = true);
67
-        $ciphertext = base64_encode($iv.$hmac.$ciphertext_raw);
54
+	/**
55
+	 * Encrypt and then sign some cleartext
56
+	 *
57
+	 * @param string $cleartext - The cleartext to encrypt and sign
58
+	 * @return string - The encrypted-and-signed message as base64 ASCII.
59
+	 */
60
+	public function encrypt($cleartext)
61
+	{
62
+		$cipher = "AES-256-CBC";
63
+		$ivlen = openssl_cipher_iv_length($cipher);
64
+		$iv = openssl_random_pseudo_bytes($ivlen);
65
+		$ciphertext_raw = openssl_encrypt($cleartext, $cipher, $this->saltedKey, $options = OPENSSL_RAW_DATA, $iv);
66
+		$hmac = hash_hmac('sha256', $ciphertext_raw, $this->saltedKey, $as_binary = true);
67
+		$ciphertext = base64_encode($iv.$hmac.$ciphertext_raw);
68 68
 
69
-        return base64_encode($iv.$hmac.$ciphertext_raw);
70
-    }
69
+		return base64_encode($iv.$hmac.$ciphertext_raw);
70
+	}
71 71
 
72
-    /**
73
-     * Check the signature on an encrypted-and-signed message, and if valid
74
-     * decrypt the content
75
-     *
76
-     * @param string $data - The encrypted-and-signed message as base64 ASCII
77
-     *
78
-     * @return bool|string - The decrypted cleartext or false if signature failed
79
-     */
80
-    public function decrypt($data)
81
-    {
82
-        $c = base64_decode($data);
83
-        $cipher = "AES-256-CBC";
84
-        $ivlen = openssl_cipher_iv_length($cipher);
85
-        $iv = substr($c, 0, $ivlen);
86
-        $hmac = substr($c, $ivlen, $sha2len = 32);
87
-        $ciphertext_raw = substr($c, $ivlen+$sha2len);
88
-        $cleartext = openssl_decrypt($ciphertext_raw, $cipher, $this->saltedKey, $options = OPENSSL_RAW_DATA, $iv);
89
-        $calcmac = hash_hmac('sha256', $ciphertext_raw, $this->saltedKey, $as_binary = true);
72
+	/**
73
+	 * Check the signature on an encrypted-and-signed message, and if valid
74
+	 * decrypt the content
75
+	 *
76
+	 * @param string $data - The encrypted-and-signed message as base64 ASCII
77
+	 *
78
+	 * @return bool|string - The decrypted cleartext or false if signature failed
79
+	 */
80
+	public function decrypt($data)
81
+	{
82
+		$c = base64_decode($data);
83
+		$cipher = "AES-256-CBC";
84
+		$ivlen = openssl_cipher_iv_length($cipher);
85
+		$iv = substr($c, 0, $ivlen);
86
+		$hmac = substr($c, $ivlen, $sha2len = 32);
87
+		$ciphertext_raw = substr($c, $ivlen+$sha2len);
88
+		$cleartext = openssl_decrypt($ciphertext_raw, $cipher, $this->saltedKey, $options = OPENSSL_RAW_DATA, $iv);
89
+		$calcmac = hash_hmac('sha256', $ciphertext_raw, $this->saltedKey, $as_binary = true);
90 90
 
91
-        if (hash_equals($hmac, $calcmac)) {
92
-            return $cleartext;
93
-        }
91
+		if (hash_equals($hmac, $calcmac)) {
92
+			return $cleartext;
93
+		}
94 94
 
95
-        return false;
96
-    }
95
+		return false;
96
+	}
97 97
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -84,7 +84,7 @@
 block discarded – undo
84 84
         $ivlen = openssl_cipher_iv_length($cipher);
85 85
         $iv = substr($c, 0, $ivlen);
86 86
         $hmac = substr($c, $ivlen, $sha2len = 32);
87
-        $ciphertext_raw = substr($c, $ivlen+$sha2len);
87
+        $ciphertext_raw = substr($c, $ivlen + $sha2len);
88 88
         $cleartext = openssl_decrypt($ciphertext_raw, $cipher, $this->saltedKey, $options = OPENSSL_RAW_DATA, $iv);
89 89
         $calcmac = hash_hmac('sha256', $ciphertext_raw, $this->saltedKey, $as_binary = true);
90 90
 
Please login to merge, or discard this patch.
src/Store/CookieStore.php 3 patches
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -4,7 +4,6 @@
 block discarded – undo
4 4
 
5 5
 use SilverStripe\Control\Cookie;
6 6
 use SilverStripe\HybridSessions\Crypto\CryptoHandler;
7
-use SilverStripe\Core\Config\Config;
8 7
 use SilverStripe\Core\Injector\Injector;
9 8
 
10 9
 /**
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -111,7 +111,7 @@  discard block
 block discarded – undo
111 111
 
112 112
         // Verify expiration
113 113
         if ($cookieData) {
114
-            $expiry = (int)substr($cookieData, 0, 10);
114
+            $expiry = (int) substr($cookieData, 0, 10);
115 115
             $data = substr($cookieData, 10);
116 116
 
117 117
             if ($expiry > $this->getNow()) {
@@ -148,11 +148,11 @@  discard block
 block discarded – undo
148 148
 
149 149
         // Restore the known good cookie value
150 150
         $this->currentCookieData = $this->crypto->encrypt(
151
-            sprintf('%010u', $expiry) . $session_data
151
+            sprintf('%010u', $expiry).$session_data
152 152
         );
153 153
 
154 154
         // Respect auto-expire on browser close for the session cookie (in case the cookie lifetime is zero)
155
-        $cookieLifetime = min((int)$params['lifetime'], $lifetime);
155
+        $cookieLifetime = min((int) $params['lifetime'], $lifetime);
156 156
 
157 157
         Cookie::set(
158 158
             $this->cookie,
Please login to merge, or discard this patch.
Indentation   +180 added lines, -180 removed lines patch added patch discarded remove patch
@@ -22,184 +22,184 @@
 block discarded – undo
22 22
 class CookieStore extends BaseStore
23 23
 {
24 24
 
25
-    /**
26
-     * Maximum length of a cookie value in characters
27
-     *
28
-     * @var int
29
-     * @config
30
-     */
31
-    private static $max_length = 1024;
32
-
33
-    /**
34
-     * Encryption service
35
-     *
36
-     * @var HybridSessionStore_Crypto
37
-     */
38
-    protected $crypto;
39
-
40
-    /**
41
-     * Name of cookie
42
-     *
43
-     * @var string
44
-     */
45
-    protected $cookie;
46
-
47
-    /**
48
-     * Known unmodified value of this cookie. If the cookie backend has been read into the application,
49
-     * then the backend is unable to verify the modification state of this value internally within the
50
-     * system, so this will be left null unless written back.
51
-     *
52
-     * If the content exceeds max_length then the backend can also not maintain this cookie, also
53
-     * setting this variable to null.
54
-     *
55
-     * @var string
56
-     */
57
-    protected $currentCookieData;
58
-
59
-    public function open($save_path, $name)
60
-    {
61
-        $this->cookie = $name.'_2';
62
-
63
-        // Read the incoming value, then clear the cookie - we might not be able
64
-        // to do so later if write() is called after headers are sent
65
-        // This is intended to force a failover to the database store if the
66
-        // modified session cannot be emitted.
67
-        $this->currentCookieData = Cookie::get($this->cookie);
68
-
69
-        if ($this->currentCookieData) {
70
-            Cookie::set($this->cookie, '');
71
-        }
72
-    }
73
-
74
-    public function close()
75
-    {
76
-    }
77
-
78
-    /**
79
-     * Get the cryptography store for the specified session
80
-     *
81
-     * @param string $session_id
82
-     * @return HybridSessionStore_Crypto
83
-     */
84
-    protected function getCrypto($session_id)
85
-    {
86
-        $key = $this->getKey();
87
-
88
-        if (!$key) {
89
-            return null;
90
-        }
91
-
92
-        if (!$this->crypto || $this->crypto->getSalt() != $session_id) {
93
-            $this->crypto = Injector::inst()->create(CryptoHandler::class, $key, $session_id);
94
-        }
95
-
96
-        return $this->crypto;
97
-    }
98
-
99
-    public function read($session_id)
100
-    {
101
-        // Check ability to safely decrypt content
102
-        if (!$this->currentCookieData
103
-            || !($crypto = $this->getCrypto($session_id))
104
-        ) {
105
-            return;
106
-        }
107
-
108
-        // Decrypt and invalidate old data
109
-        $cookieData = $crypto->decrypt($this->currentCookieData);
110
-        $this->currentCookieData = null;
111
-
112
-        // Verify expiration
113
-        if ($cookieData) {
114
-            $expiry = (int)substr($cookieData, 0, 10);
115
-            $data = substr($cookieData, 10);
116
-
117
-            if ($expiry > $this->getNow()) {
118
-                return $data;
119
-            }
120
-        }
121
-    }
122
-
123
-    /**
124
-     * Determine if the session could be verifably written to cookie storage
125
-     *
126
-     * @return bool
127
-     */
128
-    protected function canWrite()
129
-    {
130
-        return !headers_sent();
131
-    }
132
-
133
-    public function write($session_id, $session_data)
134
-    {
135
-        $canWrite = $this->canWrite();
136
-        $isExceedingCookieLimit = (strlen($session_data) > static::config()->get('max_length'));
137
-        $crypto = $this->getCrypto($session_id);
138
-
139
-        // Check ability to safely encrypt and write content
140
-        if (!$canWrite || $isExceedingCookieLimit || !$crypto) {
141
-            if ($canWrite && $isExceedingCookieLimit) {
142
-                $params = session_get_cookie_params();
143
-                // Clear stored cookie value and cookie when length exceeds the set limit
144
-                $this->currentCookieData = null;
145
-                Cookie::set(
146
-                    $this->cookie,
147
-                    '',
148
-                    0,
149
-                    $params['path'],
150
-                    $params['domain'],
151
-                    $params['secure'],
152
-                    $params['httponly']
153
-                );
154
-            }
155
-
156
-            return false;
157
-        }
158
-
159
-        // Prepare content for write
160
-        $params = session_get_cookie_params();
161
-        // Total max lifetime, stored internally
162
-        $lifetime = $this->getLifetime();
163
-        $expiry = $this->getNow() + $lifetime;
164
-
165
-        // Restore the known good cookie value
166
-        $this->currentCookieData = $this->crypto->encrypt(
167
-            sprintf('%010u', $expiry) . $session_data
168
-        );
169
-
170
-        // Respect auto-expire on browser close for the session cookie (in case the cookie lifetime is zero)
171
-        $cookieLifetime = min((int)$params['lifetime'], $lifetime);
172
-
173
-        Cookie::set(
174
-            $this->cookie,
175
-            $this->currentCookieData,
176
-            $cookieLifetime / 86400,
177
-            $params['path'],
178
-            $params['domain'],
179
-            $params['secure'],
180
-            $params['httponly']
181
-        );
182
-
183
-        return true;
184
-    }
185
-
186
-    public function destroy($session_id)
187
-    {
188
-        $this->currentCookieData = null;
189
-
190
-        $params = session_get_cookie_params();
191
-
192
-        Cookie::force_expiry(
193
-            $this->cookie,
194
-            $params['path'],
195
-            $params['domain'],
196
-            $params['secure'],
197
-            $params['httponly']
198
-        );
199
-    }
200
-
201
-    public function gc($maxlifetime)
202
-    {
203
-        // NOP
204
-    }
25
+	/**
26
+	 * Maximum length of a cookie value in characters
27
+	 *
28
+	 * @var int
29
+	 * @config
30
+	 */
31
+	private static $max_length = 1024;
32
+
33
+	/**
34
+	 * Encryption service
35
+	 *
36
+	 * @var HybridSessionStore_Crypto
37
+	 */
38
+	protected $crypto;
39
+
40
+	/**
41
+	 * Name of cookie
42
+	 *
43
+	 * @var string
44
+	 */
45
+	protected $cookie;
46
+
47
+	/**
48
+	 * Known unmodified value of this cookie. If the cookie backend has been read into the application,
49
+	 * then the backend is unable to verify the modification state of this value internally within the
50
+	 * system, so this will be left null unless written back.
51
+	 *
52
+	 * If the content exceeds max_length then the backend can also not maintain this cookie, also
53
+	 * setting this variable to null.
54
+	 *
55
+	 * @var string
56
+	 */
57
+	protected $currentCookieData;
58
+
59
+	public function open($save_path, $name)
60
+	{
61
+		$this->cookie = $name.'_2';
62
+
63
+		// Read the incoming value, then clear the cookie - we might not be able
64
+		// to do so later if write() is called after headers are sent
65
+		// This is intended to force a failover to the database store if the
66
+		// modified session cannot be emitted.
67
+		$this->currentCookieData = Cookie::get($this->cookie);
68
+
69
+		if ($this->currentCookieData) {
70
+			Cookie::set($this->cookie, '');
71
+		}
72
+	}
73
+
74
+	public function close()
75
+	{
76
+	}
77
+
78
+	/**
79
+	 * Get the cryptography store for the specified session
80
+	 *
81
+	 * @param string $session_id
82
+	 * @return HybridSessionStore_Crypto
83
+	 */
84
+	protected function getCrypto($session_id)
85
+	{
86
+		$key = $this->getKey();
87
+
88
+		if (!$key) {
89
+			return null;
90
+		}
91
+
92
+		if (!$this->crypto || $this->crypto->getSalt() != $session_id) {
93
+			$this->crypto = Injector::inst()->create(CryptoHandler::class, $key, $session_id);
94
+		}
95
+
96
+		return $this->crypto;
97
+	}
98
+
99
+	public function read($session_id)
100
+	{
101
+		// Check ability to safely decrypt content
102
+		if (!$this->currentCookieData
103
+			|| !($crypto = $this->getCrypto($session_id))
104
+		) {
105
+			return;
106
+		}
107
+
108
+		// Decrypt and invalidate old data
109
+		$cookieData = $crypto->decrypt($this->currentCookieData);
110
+		$this->currentCookieData = null;
111
+
112
+		// Verify expiration
113
+		if ($cookieData) {
114
+			$expiry = (int)substr($cookieData, 0, 10);
115
+			$data = substr($cookieData, 10);
116
+
117
+			if ($expiry > $this->getNow()) {
118
+				return $data;
119
+			}
120
+		}
121
+	}
122
+
123
+	/**
124
+	 * Determine if the session could be verifably written to cookie storage
125
+	 *
126
+	 * @return bool
127
+	 */
128
+	protected function canWrite()
129
+	{
130
+		return !headers_sent();
131
+	}
132
+
133
+	public function write($session_id, $session_data)
134
+	{
135
+		$canWrite = $this->canWrite();
136
+		$isExceedingCookieLimit = (strlen($session_data) > static::config()->get('max_length'));
137
+		$crypto = $this->getCrypto($session_id);
138
+
139
+		// Check ability to safely encrypt and write content
140
+		if (!$canWrite || $isExceedingCookieLimit || !$crypto) {
141
+			if ($canWrite && $isExceedingCookieLimit) {
142
+				$params = session_get_cookie_params();
143
+				// Clear stored cookie value and cookie when length exceeds the set limit
144
+				$this->currentCookieData = null;
145
+				Cookie::set(
146
+					$this->cookie,
147
+					'',
148
+					0,
149
+					$params['path'],
150
+					$params['domain'],
151
+					$params['secure'],
152
+					$params['httponly']
153
+				);
154
+			}
155
+
156
+			return false;
157
+		}
158
+
159
+		// Prepare content for write
160
+		$params = session_get_cookie_params();
161
+		// Total max lifetime, stored internally
162
+		$lifetime = $this->getLifetime();
163
+		$expiry = $this->getNow() + $lifetime;
164
+
165
+		// Restore the known good cookie value
166
+		$this->currentCookieData = $this->crypto->encrypt(
167
+			sprintf('%010u', $expiry) . $session_data
168
+		);
169
+
170
+		// Respect auto-expire on browser close for the session cookie (in case the cookie lifetime is zero)
171
+		$cookieLifetime = min((int)$params['lifetime'], $lifetime);
172
+
173
+		Cookie::set(
174
+			$this->cookie,
175
+			$this->currentCookieData,
176
+			$cookieLifetime / 86400,
177
+			$params['path'],
178
+			$params['domain'],
179
+			$params['secure'],
180
+			$params['httponly']
181
+		);
182
+
183
+		return true;
184
+	}
185
+
186
+	public function destroy($session_id)
187
+	{
188
+		$this->currentCookieData = null;
189
+
190
+		$params = session_get_cookie_params();
191
+
192
+		Cookie::force_expiry(
193
+			$this->cookie,
194
+			$params['path'],
195
+			$params['domain'],
196
+			$params['secure'],
197
+			$params['httponly']
198
+		);
199
+	}
200
+
201
+	public function gc($maxlifetime)
202
+	{
203
+		// NOP
204
+	}
205 205
 }
Please login to merge, or discard this patch.
src/Store/BaseStore.php 2 patches
Indentation   +52 added lines, -52 removed lines patch added patch discarded remove patch
@@ -8,56 +8,56 @@
 block discarded – undo
8 8
 
9 9
 abstract class BaseStore implements SessionHandlerInterface
10 10
 {
11
-    use Configurable;
12
-
13
-    /**
14
-     * Session secret key
15
-     *
16
-     * @var string
17
-     */
18
-    protected $key = null;
19
-
20
-    /**
21
-     * Assign a new session secret key
22
-     *
23
-     * @param string $key
24
-     */
25
-    public function setKey($key)
26
-    {
27
-        $this->key = $key;
28
-    }
29
-
30
-    /**
31
-     * Get the session secret key
32
-     *
33
-     * @return string
34
-     */
35
-    protected function getKey()
36
-    {
37
-        return $this->key;
38
-    }
39
-
40
-    /**
41
-     * Get lifetime in number of seconds
42
-     *
43
-     * @return int
44
-     */
45
-    protected function getLifetime()
46
-    {
47
-        $params = session_get_cookie_params();
48
-        $cookieLifetime = (int)$params['lifetime'];
49
-        $gcLifetime = (int)ini_get('session.gc_maxlifetime');
50
-
51
-        return $cookieLifetime ? min($cookieLifetime, $gcLifetime) : $gcLifetime;
52
-    }
53
-
54
-    /**
55
-     * Gets the current unix timestamp
56
-     *
57
-     * @return int
58
-     */
59
-    protected function getNow()
60
-    {
61
-        return (int) DBDatetime::now()->getTimestamp();
62
-    }
11
+	use Configurable;
12
+
13
+	/**
14
+	 * Session secret key
15
+	 *
16
+	 * @var string
17
+	 */
18
+	protected $key = null;
19
+
20
+	/**
21
+	 * Assign a new session secret key
22
+	 *
23
+	 * @param string $key
24
+	 */
25
+	public function setKey($key)
26
+	{
27
+		$this->key = $key;
28
+	}
29
+
30
+	/**
31
+	 * Get the session secret key
32
+	 *
33
+	 * @return string
34
+	 */
35
+	protected function getKey()
36
+	{
37
+		return $this->key;
38
+	}
39
+
40
+	/**
41
+	 * Get lifetime in number of seconds
42
+	 *
43
+	 * @return int
44
+	 */
45
+	protected function getLifetime()
46
+	{
47
+		$params = session_get_cookie_params();
48
+		$cookieLifetime = (int)$params['lifetime'];
49
+		$gcLifetime = (int)ini_get('session.gc_maxlifetime');
50
+
51
+		return $cookieLifetime ? min($cookieLifetime, $gcLifetime) : $gcLifetime;
52
+	}
53
+
54
+	/**
55
+	 * Gets the current unix timestamp
56
+	 *
57
+	 * @return int
58
+	 */
59
+	protected function getNow()
60
+	{
61
+		return (int) DBDatetime::now()->getTimestamp();
62
+	}
63 63
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -45,8 +45,8 @@
 block discarded – undo
45 45
     protected function getLifetime()
46 46
     {
47 47
         $params = session_get_cookie_params();
48
-        $cookieLifetime = (int)$params['lifetime'];
49
-        $gcLifetime = (int)ini_get('session.gc_maxlifetime');
48
+        $cookieLifetime = (int) $params['lifetime'];
49
+        $gcLifetime = (int) ini_get('session.gc_maxlifetime');
50 50
 
51 51
         return $cookieLifetime ? min($cookieLifetime, $gcLifetime) : $gcLifetime;
52 52
     }
Please login to merge, or discard this patch.
src/Model/HybridSessionDataObject.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -6,18 +6,18 @@
 block discarded – undo
6 6
 
7 7
 class HybridSessionDataObject extends DataObject
8 8
 {
9
-    private static $db = [
10
-        'SessionID' => 'Varchar(64)',
11
-        'Expiry' => 'Int',
12
-        'Data' => 'Text'
13
-    ];
9
+	private static $db = [
10
+		'SessionID' => 'Varchar(64)',
11
+		'Expiry' => 'Int',
12
+		'Data' => 'Text'
13
+	];
14 14
 
15
-    private static $indexes = [
16
-        'SessionID' => [
17
-            'type' => 'unique'
18
-        ],
19
-        'Expiry' => true
20
-    ];
15
+	private static $indexes = [
16
+		'SessionID' => [
17
+			'type' => 'unique'
18
+		],
19
+		'Expiry' => true
20
+	];
21 21
 
22
-    private static $table_name = 'HybridSessionDataObject';
22
+	private static $table_name = 'HybridSessionDataObject';
23 23
 }
Please login to merge, or discard this patch.
src/Crypto/CryptoHandler.php 1 patch
Indentation   +20 added lines, -20 removed lines patch added patch discarded remove patch
@@ -5,27 +5,27 @@
 block discarded – undo
5 5
 interface CryptoHandler
6 6
 {
7 7
 
8
-    /**
9
-     * @param string $data
10
-     *
11
-     * @return string
12
-     */
13
-    public function encrypt($data);
8
+	/**
9
+	 * @param string $data
10
+	 *
11
+	 * @return string
12
+	 */
13
+	public function encrypt($data);
14 14
 
15
-    /**
16
-     * @param string $data
17
-     *
18
-     * @return string
19
-     */
20
-    public function decrypt($data);
15
+	/**
16
+	 * @param string $data
17
+	 *
18
+	 * @return string
19
+	 */
20
+	public function decrypt($data);
21 21
 
22
-    /**
23
-     * @return string
24
-     */
25
-    public function getKey();
22
+	/**
23
+	 * @return string
24
+	 */
25
+	public function getKey();
26 26
 
27
-    /**
28
-     * @return string
29
-     */
30
-    public function getSalt();
27
+	/**
28
+	 * @return string
29
+	 */
30
+	public function getSalt();
31 31
 }
Please login to merge, or discard this patch.
src/Control/HybridSessionMiddleware.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -8,25 +8,25 @@
 block discarded – undo
8 8
 
9 9
 class HybridSessionMiddleware implements HTTPMiddleware
10 10
 {
11
-    public function process(HTTPRequest $request, callable $delegate)
12
-    {
13
-        try {
14
-            // Start session and execute
15
-            $request->getSession()->init($request);
11
+	public function process(HTTPRequest $request, callable $delegate)
12
+	{
13
+		try {
14
+			// Start session and execute
15
+			$request->getSession()->init($request);
16 16
 
17
-            // Generate output
18
-            $response = $delegate($request);
19
-        } finally {
20
-            // Save session data, even if there was an exception
21
-            // Note that save() will start/resume the session if required.
22
-            $request->getSession()->save($request);
17
+			// Generate output
18
+			$response = $delegate($request);
19
+		} finally {
20
+			// Save session data, even if there was an exception
21
+			// Note that save() will start/resume the session if required.
22
+			$request->getSession()->save($request);
23 23
 
24
-            if (HybridSession::is_enabled()) {
25
-                // Close the session
26
-                session_write_close();
27
-            }
28
-        }
24
+			if (HybridSession::is_enabled()) {
25
+				// Close the session
26
+				session_write_close();
27
+			}
28
+		}
29 29
 
30
-        return $response;
31
-    }
30
+		return $response;
31
+	}
32 32
 }
Please login to merge, or discard this patch.
tests/ConfigurationTest.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -9,12 +9,12 @@
 block discarded – undo
9 9
 
10 10
 class ConfigurationTest extends SapphireTest
11 11
 {
12
-    public function testHybridSessionsSessionMiddlewareReplacesCore()
13
-    {
14
-        $this->assertInstanceOf(
15
-            HybridSessionMiddleware::class,
16
-            Injector::inst()->get(SessionMiddleware::class),
17
-            'HybridSession\'s middleware should replace the default SessionMiddleware'
18
-        );
19
-    }
12
+	public function testHybridSessionsSessionMiddlewareReplacesCore()
13
+	{
14
+		$this->assertInstanceOf(
15
+			HybridSessionMiddleware::class,
16
+			Injector::inst()->get(SessionMiddleware::class),
17
+			'HybridSession\'s middleware should replace the default SessionMiddleware'
18
+		);
19
+	}
20 20
 }
Please login to merge, or discard this patch.