-
Notifications
You must be signed in to change notification settings - Fork 6
/
openid_connect_sso.module
182 lines (163 loc) · 4.82 KB
/
openid_connect_sso.module
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
<?php
/**
* @file
* Provides basic SSO functionality.
*/
/**
* Get the configured cookie domain.
*
* @return string
*/
function openid_connect_sso_get_cookie_domain() {
$cookie_domain = \Drupal::config('openid_connect_sso.settings')->get('cookie_domain');
// @see also https://www.drupal.org/files/issues/cookie_name_fix_when_cookie_variable_is_empty-2513282-3.patch
if (empty($cookie_domain)) {
$cookie_domain = $_SERVER['HTTP_HOST'];
}
return ltrim($cookie_domain, '.');
}
/**
* Get the cookie name for a given operation.
*
* @param string $op
* The operation: 'logout' or 'login'.
* @param bool $as_key
* Whether to return the name as appropriate for an array key in $_COOKIE,
* i.e. with '.' replaced with '_'.
* @param bool $with_domain
* Whether to add the domain name to the cookie name.
*
* @throws InvalidArgumentException for an invalid $op
*
* @return string
*/
function openid_connect_sso_get_cookie_name($op, $as_key = FALSE, $with_domain = FALSE) {
switch ($op) {
case 'logout':
$cookie_name = 'Drupal.visitor.SSOLogout';
break;
case 'login':
$cookie_name = 'Drupal.visitor.SSOLogin';
break;
default:
throw new InvalidArgumentException('Invalid operation: ' . $op);
}
if ($with_domain) {
$cookie_name .= '_' . openid_connect_sso_get_cookie_domain();
}
if ($as_key) {
return str_replace('.', '_', $cookie_name);
}
return $cookie_name;
}
/**
* Detect whether a valid cookie is set for the correct domain.
*
* @param string $op
* The operation: 'logout' or 'login'.
*
* @return bool
* TRUE if the cookie is set, FALSE if not.
*/
function openid_connect_sso_detect_cookie($op) {
$name_as_key = openid_connect_sso_get_cookie_name($op, TRUE);
if (!empty($_COOKIE[$name_as_key])) {
return TRUE;
}
$with_domain = openid_connect_sso_get_cookie_name($op, TRUE, TRUE);
return !empty($_COOKIE[$with_domain]);
}
/**
* Ensure that a cookie is removed for the correct domain.
*
* @param string $op
*/
function openid_connect_sso_remove_cookie($op) {
$cookie_name = openid_connect_sso_get_cookie_name($op);
$name_as_key = openid_connect_sso_get_cookie_name($op, TRUE);
$cookie_domain = openid_connect_sso_get_cookie_domain();
if (isset($_COOKIE[$name_as_key])) {
setcookie($cookie_name, '', time() - 3600, '/', $cookie_domain);
unset($_COOKIE[$name_as_key]);
}
$extended_name_as_key = $name_as_key . '_' . str_replace('.', '_', $cookie_domain);
if (isset($_COOKIE[$extended_name_as_key])) {
$extended_name = $cookie_name . '_' . $cookie_domain;
setcookie($extended_name, '', time() - 3600, '/', $cookie_domain);
unset($_COOKIE[$extended_name_as_key]);
}
}
/**
* Implements hook_user_login().
*
* Request a redirect after a successful login.
*/
function openid_connect_sso_user_login($account) {
// The presence of a cookie or session param would indicate that the user
// is already in the middle of logging into the network.
$has_cookie = openid_connect_sso_detect_cookie('login');
$has_session_param = isset($_SESSION['oauth2_server_authorize']);
if (!$has_cookie && !$has_session_param) {
openid_connect_sso_set_redirect('login');
}
if ($has_cookie) {
openid_connect_sso_remove_cookie('login');
}
}
/**
* Implements hook_user_logout().
*
* Request a redirect after a successful logout.
*/
function openid_connect_sso_user_logout($account) {
// The presence of a cookie would indicate that the user is already
// in the middle of logging out of the network.
if (!openid_connect_sso_detect_cookie('logout')) {
openid_connect_sso_set_redirect('logout');
}
else {
// Remove the cookie, it has done its purpose.
openid_connect_sso_remove_cookie('logout');
}
}
/**
* Sets an SSO redirect to be performed on page shutdown.
*
* @param $type
* The type of redirect to perform. "login" or "logout".
*/
function openid_connect_sso_set_redirect($type = NULL) {
$redirect = &drupal_static(__FUNCTION__, NULL);
if (isset($type)) {
$redirect = $type;
}
return $redirect;
}
/**
* Returns the SSO redirect to be performed on page shutdown, if any.
*/
function openid_connect_sso_get_redirect() {
return openid_connect_sso_set_redirect();
}
/**
* Returns the SSO script url based on the configured location.
*/
function openid_connect_sso_get_script_url() {
global $base_url, $is_https;
$script_url = \Drupal::config('openid_connect_sso.settings')->get('script_url');
if ($script_url) {
return $script_url;
}
$location = \Drupal::config('openid_connect_sso.settings')->get('script_location');
if (empty($location)) {
$location = 'drupal';
}
if ($location == 'drupal') {
$url = $base_url . '/sso.php';
}
else {
$protocol = $is_https ? 'https://' : 'http://';
$url = str_replace($protocol, $protocol . 'a.', $base_url);
}
return $url;
}