-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvarnish_authcache.module
More file actions
150 lines (132 loc) · 4.45 KB
/
Copy pathvarnish_authcache.module
File metadata and controls
150 lines (132 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php
function varnish_authcache_settings_form() {
$form = array();
$form['varnish_authcache_cookie_lease_time'] = array(
'#type' => 'textfield',
'#title' => t('Lease time'),
'#description' =>
t('The duration of time the cookie Varnish will use for authenticated cache lookups will be valid. When expired a new cookie will have to be fetched from Drupal.'),
'#default_value' => variable_get('varnish_authcache_cookie_lease_time', 600),
);
$form['varnish_authcache_salt'] = array(
'#type' => 'textfield',
'#title' => t('Salt'),
'#description' =>
t('Shared secret hash-salt.'),
'#default_value' => variable_get('varnish_authcache_salt', 'test'),
);
return system_settings_form($form);
}
function varnish_authcache_menu(){
return array(
'admin/settings/varnish-authcache' => array(
'title' => 'Varnish Authcache',
'access arguments' => array('administer site configuration'),
'page callback' => 'drupal_get_form',
'page arguments' => array('varnish_authcache_settings_form'),
),
'admin/settings/varnish-authcache/settings' => array(
'title' => 'Settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -99,
)
);
}
function varnish_authcache_hash() {
$hook = 'varnish_authcache_hash';
$modules = module_implements('varnish_authcache_hash');
if(empty($modules)) {
//issue warning about no modules beeing enabled
return FALSE;
}
else {
$parts = array();
foreach($modules as $module) {
$function = $module . '_' . $hook;
if($part = call_user_func($module . '_' . $hook)) {
$parts[] = $part;
}
}
if(!empty($parts)) {
//sorting
sort($parts);
//obfuscating
$key = 'varnish_authcache_hash_' . md5(implode('', $parts));
if(!variable_get($key, FALSE)) {
variable_set($key, md5(uniqid('', TRUE)));
}
return variable_get($key, $rid);
}
//else {
// $hash FALSE;
//}
}
return FALSE;
}
//auto generate salt with uniqid?
//more safe hashing?
function varnish_authcache_signature($value) {
return md5(ip_address(). variable_get('varnish_authcache_salt', 'test') . $value);
}
function varnish_authcache_init(){
//should be treated same as session cookie, right??
global $user;
//TODO: perhaps remove uid check?
if($user->uid && $authcache_hash = varnish_authcache_hash()) {
//This whole check is pretty pointless?
//Always renew cookie instead? Could save some extra detours to the backend
if(isset($_COOKIE['DRUPAL_AC'])) {
$values = explode('.', $_COOKIE['DRUPAL_AC']);
if(count($values) === 3) {
list($hash, $expire, $sign) = $values;
//TODO: dot or not?
if(
$authcache_hash === $hash && /* same credentials as before? */
varnish_authcache_signature(implode('', array($hash, $expire))) === $sign && /* validates? */
$expire > time() /* if false browser/user may not be respecting cookie life-time */
) {
//everything in order, nothing needs to be done
//TODO: Or perhaps we should renew the cookie while we have the chance, probably
return;
}
}
}
//else refresh/create cookie
$expire = $_SERVER['REQUEST_TIME'] + (int) variable_get('varnish_authcache_cookie_lease_time', 600);
$values = array($authcache_hash, $expire);
$values[] = varnish_authcache_signature(implode('', $values));
$value = implode('.', $values);
_varnish_authcache_set_cookie('DRUPAL_AC', $value, $expire);
}
else {
//User not logged in, unset cookie
//TODO: hook into session?
varnish_authcache_cookie_destroy();
}
}
//Hook user
function varnish_authcache_user($op, &$edit, &$account, $category = NULL) {
if($op == 'logout') {
varnish_authcache_cookie_destroy();
}
}
function varnish_authcache_cookie_destroy() {
if(isset($_COOKIE['DRUPAL_AC'])){
//Do not save this in cache, if session exires and this page is served the unauthenticated version will be cached for authenticated users
drupal_set_header('Pragma: no-cache');
//Perhaps instead configure vanish to never cache on set-cookie, any side effects?
_varnish_authcache_set_cookie('DRUPAL_AC', '', $_SERVER['REQUEST_TIME'] - 3600);
//TODO: unset perhaps not really necessary
unset($_COOKIE[$key]);
}
}
function _varnish_authcache_set_cookie($name, $value, $expire) {
$params = session_get_cookie_params();
if (version_compare(PHP_VERSION, '5.2.0') === 1) {
setcookie($name, $value, $expire, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
}
else {
setcookie($name, $value, $expire, $params['path'], $params['domain'], $params['secure']);
}
}
?>