@@ -17,7 +17,7 @@ discard block |
||
17 | 17 | |
18 | 18 | // Exit if accessed directly |
19 | 19 | if (!defined('ABSPATH')) { |
20 | - exit; |
|
20 | + exit; |
|
21 | 21 | } |
22 | 22 | |
23 | 23 | use WP_Admin_Bar; |
@@ -25,154 +25,154 @@ discard block |
||
25 | 25 | |
26 | 26 | final class Admin |
27 | 27 | { |
28 | - /** |
|
29 | - * URL pointing to the "About TrustedLogin" page, shown below the Grant Access dialog. |
|
30 | - */ |
|
31 | - const ABOUT_TL_URL = 'https://www.trustedlogin.com/about/easy-and-safe/'; |
|
32 | - |
|
33 | - const ABOUT_LIVE_ACCESS_URL = 'https://www.trustedlogin.com/about/live-access/'; |
|
34 | - |
|
35 | - /** |
|
36 | - * @var Config |
|
37 | - */ |
|
38 | - private $config; |
|
39 | - |
|
40 | - /** |
|
41 | - * @var SiteAccess |
|
42 | - */ |
|
43 | - private $site_access; |
|
44 | - |
|
45 | - /** |
|
46 | - * @var SupportUser |
|
47 | - */ |
|
48 | - private $support_user; |
|
49 | - |
|
50 | - /** |
|
51 | - * @var null|Logging |
|
52 | - */ |
|
53 | - private $logging; |
|
54 | - |
|
55 | - /** |
|
56 | - * Admin constructor. |
|
57 | - * |
|
58 | - * @param Config $config |
|
59 | - */ |
|
60 | - public function __construct(Config $config, Logging $logging) |
|
61 | - { |
|
62 | - $this->config = $config; |
|
63 | - $this->logging = $logging; |
|
64 | - $this->site_access = new SiteAccess($config, $logging); |
|
65 | - $this->support_user = new SupportUser($config, $logging); |
|
66 | - } |
|
67 | - |
|
68 | - public function init() |
|
69 | - { |
|
70 | - add_action('trustedlogin/'.$this->config->ns().'/button', [$this, 'generate_button'], 10, 2); |
|
71 | - add_action('trustedlogin/'.$this->config->ns().'/users_table', [ |
|
72 | - $this, |
|
73 | - 'output_support_users', |
|
74 | - ], 20); |
|
75 | - add_action('trustedlogin/'.$this->config->ns().'/auth_screen', [$this, 'print_auth_screen'], 20); |
|
76 | - add_action('login_form_trustedlogin', [$this, 'maybe_print_request_screen'], 20); |
|
77 | - add_filter('user_row_actions', [$this, 'user_row_action_revoke'], 10, 2); |
|
78 | - add_action('admin_bar_menu', [$this, 'admin_bar_add_toolbar_items'], 100); |
|
79 | - |
|
80 | - if ($this->config->get_setting('menu')) { |
|
81 | - $menu_priority = $this->config->get_setting('menu/priority', 100); |
|
82 | - add_action('admin_menu', [$this, 'admin_menu_auth_link_page'], $menu_priority); |
|
83 | - } |
|
84 | - |
|
85 | - if ($this->config->get_setting('register_assets', true)) { |
|
86 | - add_action('admin_enqueue_scripts', [$this, 'register_assets']); |
|
87 | - add_action('login_enqueue_scripts', [$this, 'register_assets']); |
|
88 | - } |
|
89 | - |
|
90 | - add_action('trustedlogin/'.$this->config->ns().'/admin/access_revoked', [$this, 'admin_notices']); |
|
91 | - } |
|
92 | - |
|
93 | - /** |
|
94 | - * Filter: Update the actions on the users.php list for our support users. |
|
95 | - * |
|
96 | - * @since 1.0.0 |
|
97 | - * |
|
98 | - * @param array $actions |
|
99 | - * @param WP_User $user_object |
|
100 | - * |
|
101 | - * @return array |
|
102 | - */ |
|
103 | - public function user_row_action_revoke($actions, $user_object) |
|
104 | - { |
|
105 | - if (!current_user_can($this->support_user->role->get_name()) && !current_user_can('delete_users')) { |
|
106 | - return $actions; |
|
107 | - } |
|
108 | - |
|
109 | - $revoke_url = $this->support_user->get_revoke_url($user_object); |
|
110 | - |
|
111 | - if (!$revoke_url) { |
|
112 | - return $actions; |
|
113 | - } |
|
114 | - |
|
115 | - return [ |
|
116 | - 'revoke' => "<a class='trustedlogin tl-revoke submitdelete' href='".esc_url($revoke_url)."'>".esc_html__('Revoke Access', 'gravityview').'</a>', |
|
117 | - ]; |
|
118 | - } |
|
119 | - |
|
120 | - /** |
|
121 | - * Register the required scripts and styles. |
|
122 | - * |
|
123 | - * @since 1.0.0 |
|
124 | - */ |
|
125 | - public function register_assets() |
|
126 | - { |
|
127 | - $registered = []; |
|
128 | - |
|
129 | - $registered['trustedlogin-js'] = wp_register_script( |
|
130 | - 'trustedlogin-'.$this->config->ns(), |
|
131 | - $this->config->get_setting('paths/js'), |
|
132 | - ['jquery', 'wp-a11y'], |
|
133 | - Client::VERSION, |
|
134 | - true |
|
135 | - ); |
|
136 | - |
|
137 | - $registered['trustedlogin-css'] = wp_register_style( |
|
138 | - 'trustedlogin-'.$this->config->ns(), |
|
139 | - $this->config->get_setting('paths/css'), |
|
140 | - [], |
|
141 | - Client::VERSION, |
|
142 | - 'all' |
|
143 | - ); |
|
144 | - |
|
145 | - $registered_filtered = array_filter($registered); |
|
146 | - |
|
147 | - if (count($registered) !== count($registered_filtered)) { |
|
148 | - $this->logging->log('Not all scripts and styles were registered: '.print_r($registered_filtered, true), __METHOD__, 'error'); |
|
149 | - } |
|
150 | - } |
|
151 | - |
|
152 | - /** |
|
153 | - * Adds a "Revoke TrustedLogin" menu item to the admin toolbar. |
|
154 | - * |
|
155 | - * @param WP_Admin_Bar $admin_bar |
|
156 | - * |
|
157 | - * @return void |
|
158 | - */ |
|
159 | - public function admin_bar_add_toolbar_items($admin_bar) |
|
160 | - { |
|
161 | - if (!current_user_can($this->support_user->role->get_name())) { |
|
162 | - return; |
|
163 | - } |
|
164 | - |
|
165 | - if (!$admin_bar instanceof WP_Admin_Bar) { |
|
166 | - return; |
|
167 | - } |
|
168 | - |
|
169 | - $is_user_active = $this->support_user->is_active(); |
|
170 | - |
|
171 | - if (!$is_user_active) { |
|
172 | - return; |
|
173 | - } |
|
174 | - |
|
175 | - $icon = '<span style=" |
|
28 | + /** |
|
29 | + * URL pointing to the "About TrustedLogin" page, shown below the Grant Access dialog. |
|
30 | + */ |
|
31 | + const ABOUT_TL_URL = 'https://www.trustedlogin.com/about/easy-and-safe/'; |
|
32 | + |
|
33 | + const ABOUT_LIVE_ACCESS_URL = 'https://www.trustedlogin.com/about/live-access/'; |
|
34 | + |
|
35 | + /** |
|
36 | + * @var Config |
|
37 | + */ |
|
38 | + private $config; |
|
39 | + |
|
40 | + /** |
|
41 | + * @var SiteAccess |
|
42 | + */ |
|
43 | + private $site_access; |
|
44 | + |
|
45 | + /** |
|
46 | + * @var SupportUser |
|
47 | + */ |
|
48 | + private $support_user; |
|
49 | + |
|
50 | + /** |
|
51 | + * @var null|Logging |
|
52 | + */ |
|
53 | + private $logging; |
|
54 | + |
|
55 | + /** |
|
56 | + * Admin constructor. |
|
57 | + * |
|
58 | + * @param Config $config |
|
59 | + */ |
|
60 | + public function __construct(Config $config, Logging $logging) |
|
61 | + { |
|
62 | + $this->config = $config; |
|
63 | + $this->logging = $logging; |
|
64 | + $this->site_access = new SiteAccess($config, $logging); |
|
65 | + $this->support_user = new SupportUser($config, $logging); |
|
66 | + } |
|
67 | + |
|
68 | + public function init() |
|
69 | + { |
|
70 | + add_action('trustedlogin/'.$this->config->ns().'/button', [$this, 'generate_button'], 10, 2); |
|
71 | + add_action('trustedlogin/'.$this->config->ns().'/users_table', [ |
|
72 | + $this, |
|
73 | + 'output_support_users', |
|
74 | + ], 20); |
|
75 | + add_action('trustedlogin/'.$this->config->ns().'/auth_screen', [$this, 'print_auth_screen'], 20); |
|
76 | + add_action('login_form_trustedlogin', [$this, 'maybe_print_request_screen'], 20); |
|
77 | + add_filter('user_row_actions', [$this, 'user_row_action_revoke'], 10, 2); |
|
78 | + add_action('admin_bar_menu', [$this, 'admin_bar_add_toolbar_items'], 100); |
|
79 | + |
|
80 | + if ($this->config->get_setting('menu')) { |
|
81 | + $menu_priority = $this->config->get_setting('menu/priority', 100); |
|
82 | + add_action('admin_menu', [$this, 'admin_menu_auth_link_page'], $menu_priority); |
|
83 | + } |
|
84 | + |
|
85 | + if ($this->config->get_setting('register_assets', true)) { |
|
86 | + add_action('admin_enqueue_scripts', [$this, 'register_assets']); |
|
87 | + add_action('login_enqueue_scripts', [$this, 'register_assets']); |
|
88 | + } |
|
89 | + |
|
90 | + add_action('trustedlogin/'.$this->config->ns().'/admin/access_revoked', [$this, 'admin_notices']); |
|
91 | + } |
|
92 | + |
|
93 | + /** |
|
94 | + * Filter: Update the actions on the users.php list for our support users. |
|
95 | + * |
|
96 | + * @since 1.0.0 |
|
97 | + * |
|
98 | + * @param array $actions |
|
99 | + * @param WP_User $user_object |
|
100 | + * |
|
101 | + * @return array |
|
102 | + */ |
|
103 | + public function user_row_action_revoke($actions, $user_object) |
|
104 | + { |
|
105 | + if (!current_user_can($this->support_user->role->get_name()) && !current_user_can('delete_users')) { |
|
106 | + return $actions; |
|
107 | + } |
|
108 | + |
|
109 | + $revoke_url = $this->support_user->get_revoke_url($user_object); |
|
110 | + |
|
111 | + if (!$revoke_url) { |
|
112 | + return $actions; |
|
113 | + } |
|
114 | + |
|
115 | + return [ |
|
116 | + 'revoke' => "<a class='trustedlogin tl-revoke submitdelete' href='".esc_url($revoke_url)."'>".esc_html__('Revoke Access', 'gravityview').'</a>', |
|
117 | + ]; |
|
118 | + } |
|
119 | + |
|
120 | + /** |
|
121 | + * Register the required scripts and styles. |
|
122 | + * |
|
123 | + * @since 1.0.0 |
|
124 | + */ |
|
125 | + public function register_assets() |
|
126 | + { |
|
127 | + $registered = []; |
|
128 | + |
|
129 | + $registered['trustedlogin-js'] = wp_register_script( |
|
130 | + 'trustedlogin-'.$this->config->ns(), |
|
131 | + $this->config->get_setting('paths/js'), |
|
132 | + ['jquery', 'wp-a11y'], |
|
133 | + Client::VERSION, |
|
134 | + true |
|
135 | + ); |
|
136 | + |
|
137 | + $registered['trustedlogin-css'] = wp_register_style( |
|
138 | + 'trustedlogin-'.$this->config->ns(), |
|
139 | + $this->config->get_setting('paths/css'), |
|
140 | + [], |
|
141 | + Client::VERSION, |
|
142 | + 'all' |
|
143 | + ); |
|
144 | + |
|
145 | + $registered_filtered = array_filter($registered); |
|
146 | + |
|
147 | + if (count($registered) !== count($registered_filtered)) { |
|
148 | + $this->logging->log('Not all scripts and styles were registered: '.print_r($registered_filtered, true), __METHOD__, 'error'); |
|
149 | + } |
|
150 | + } |
|
151 | + |
|
152 | + /** |
|
153 | + * Adds a "Revoke TrustedLogin" menu item to the admin toolbar. |
|
154 | + * |
|
155 | + * @param WP_Admin_Bar $admin_bar |
|
156 | + * |
|
157 | + * @return void |
|
158 | + */ |
|
159 | + public function admin_bar_add_toolbar_items($admin_bar) |
|
160 | + { |
|
161 | + if (!current_user_can($this->support_user->role->get_name())) { |
|
162 | + return; |
|
163 | + } |
|
164 | + |
|
165 | + if (!$admin_bar instanceof WP_Admin_Bar) { |
|
166 | + return; |
|
167 | + } |
|
168 | + |
|
169 | + $is_user_active = $this->support_user->is_active(); |
|
170 | + |
|
171 | + if (!$is_user_active) { |
|
172 | + return; |
|
173 | + } |
|
174 | + |
|
175 | + $icon = '<span style=" |
|
176 | 176 | height: 32px; |
177 | 177 | width: 23px; |
178 | 178 | margin: 0 1px; |
@@ -182,142 +182,142 @@ discard block |
||
182 | 182 | background-size: 22px 23px; |
183 | 183 | "></span>'; |
184 | 184 | |
185 | - $admin_bar->add_menu([ |
|
186 | - 'id' => 'tl-'.$this->config->ns().'-revoke', |
|
187 | - 'title' => $icon.esc_html__('Revoke TrustedLogin', 'gravityview'), |
|
188 | - 'href' => $this->support_user->get_revoke_url('all'), |
|
189 | - 'meta' => [ |
|
190 | - 'class' => 'tl-destroy-session', |
|
191 | - ], |
|
192 | - ]); |
|
193 | - } |
|
194 | - |
|
195 | - /** |
|
196 | - * Generates the auth link page. |
|
197 | - * |
|
198 | - * This simulates the addition of an admin submenu item with null as the menu location |
|
199 | - * |
|
200 | - * @since 1.0.0 |
|
201 | - * |
|
202 | - * @return void |
|
203 | - */ |
|
204 | - public function admin_menu_auth_link_page() |
|
205 | - { |
|
206 | - $parent_slug = $this->config->get_setting('menu/slug', null); |
|
207 | - |
|
208 | - // When false, there will be no menus added. |
|
209 | - if (false === $parent_slug) { |
|
210 | - return; |
|
211 | - } |
|
212 | - |
|
213 | - $ns = $this->config->ns(); |
|
214 | - |
|
215 | - $menu_slug = apply_filters('trustedlogin/'.$this->config->ns().'/admin/menu/menu_slug', 'grant-'.$ns.'-access'); |
|
216 | - |
|
217 | - $menu_title = $this->config->get_setting('menu/title', esc_html__('Grant Support Access', 'gravityview')); |
|
218 | - |
|
219 | - // If empty (null or empty string), add top-level menu |
|
220 | - if (empty($parent_slug)) { |
|
221 | - add_menu_page( |
|
222 | - $menu_title, |
|
223 | - $menu_title, |
|
224 | - 'create_users', |
|
225 | - $menu_slug, |
|
226 | - [$this, 'print_auth_screen'], |
|
227 | - $this->config->get_setting('menu/icon_url', ''), |
|
228 | - $this->config->get_setting('menu/position', null) |
|
229 | - ); |
|
230 | - |
|
231 | - return; |
|
232 | - } |
|
233 | - |
|
234 | - add_submenu_page( |
|
235 | - $parent_slug, |
|
236 | - $menu_title, |
|
237 | - $menu_title, |
|
238 | - 'create_users', |
|
239 | - $menu_slug, |
|
240 | - [$this, 'print_auth_screen'], |
|
241 | - $this->config->get_setting('menu/position', null) |
|
242 | - ); |
|
243 | - } |
|
244 | - |
|
245 | - /** |
|
246 | - * Is this a login screen and should TrustedLogin override the login screen for the current namespace? |
|
247 | - * |
|
248 | - * @return bool |
|
249 | - */ |
|
250 | - private function is_login_screen() |
|
251 | - { |
|
252 | - return did_action('login_init') && isset($_GET['ns']) && $_GET['ns'] === $this->config->ns(); |
|
253 | - } |
|
254 | - |
|
255 | - /** |
|
256 | - * If the current request is a valid login screen override, print the TrustedLogin request screen. |
|
257 | - * |
|
258 | - * @return void |
|
259 | - */ |
|
260 | - public function maybe_print_request_screen() |
|
261 | - { |
|
262 | - if (!$this->is_login_screen()) { |
|
263 | - return; |
|
264 | - } |
|
265 | - |
|
266 | - // Once logged-in, take user back to auth request screen. |
|
267 | - if (!is_user_logged_in()) { |
|
268 | - $_REQUEST['redirect_to'] = site_url(add_query_arg([])); |
|
269 | - |
|
270 | - return; |
|
271 | - } |
|
272 | - |
|
273 | - if (!current_user_can('create_users')) { |
|
274 | - return; |
|
275 | - } |
|
276 | - |
|
277 | - $this->print_request_screen(); |
|
278 | - } |
|
279 | - |
|
280 | - public function print_request_screen() |
|
281 | - { |
|
282 | - global $interim_login, $wp_version; |
|
283 | - |
|
284 | - // Don't output a "← Back to site" link on the login page |
|
285 | - $interim_login = true; |
|
286 | - |
|
287 | - // The login_headertitle filter was deprecated in WP 5.2.0 for login_headertext |
|
288 | - if (version_compare($wp_version, '5.2.0', '<')) { |
|
289 | - add_filter('login_headertitle', '__return_empty_string'); |
|
290 | - } else { |
|
291 | - add_filter('login_headertext', '__return_empty_string'); |
|
292 | - } |
|
293 | - |
|
294 | - add_filter('login_headerurl', function () { |
|
295 | - return $this->config->get_setting('vendor/website'); |
|
296 | - }); |
|
297 | - |
|
298 | - login_header(); |
|
299 | - |
|
300 | - wp_enqueue_style('common'); |
|
301 | - |
|
302 | - wp_add_inline_style('common', $this->get_login_inline_css()); |
|
303 | - |
|
304 | - echo $this->get_auth_screen(); |
|
305 | - |
|
306 | - login_footer(); |
|
307 | - |
|
308 | - exit(); |
|
309 | - } |
|
310 | - |
|
311 | - /** |
|
312 | - * Returns inline CSS overrides for the `common` CSS dependency. |
|
313 | - * |
|
314 | - * @since 1.0.0 |
|
315 | - * |
|
316 | - * @return string |
|
317 | - */ |
|
318 | - private function get_login_inline_css() |
|
319 | - { |
|
320 | - return ' |
|
185 | + $admin_bar->add_menu([ |
|
186 | + 'id' => 'tl-'.$this->config->ns().'-revoke', |
|
187 | + 'title' => $icon.esc_html__('Revoke TrustedLogin', 'gravityview'), |
|
188 | + 'href' => $this->support_user->get_revoke_url('all'), |
|
189 | + 'meta' => [ |
|
190 | + 'class' => 'tl-destroy-session', |
|
191 | + ], |
|
192 | + ]); |
|
193 | + } |
|
194 | + |
|
195 | + /** |
|
196 | + * Generates the auth link page. |
|
197 | + * |
|
198 | + * This simulates the addition of an admin submenu item with null as the menu location |
|
199 | + * |
|
200 | + * @since 1.0.0 |
|
201 | + * |
|
202 | + * @return void |
|
203 | + */ |
|
204 | + public function admin_menu_auth_link_page() |
|
205 | + { |
|
206 | + $parent_slug = $this->config->get_setting('menu/slug', null); |
|
207 | + |
|
208 | + // When false, there will be no menus added. |
|
209 | + if (false === $parent_slug) { |
|
210 | + return; |
|
211 | + } |
|
212 | + |
|
213 | + $ns = $this->config->ns(); |
|
214 | + |
|
215 | + $menu_slug = apply_filters('trustedlogin/'.$this->config->ns().'/admin/menu/menu_slug', 'grant-'.$ns.'-access'); |
|
216 | + |
|
217 | + $menu_title = $this->config->get_setting('menu/title', esc_html__('Grant Support Access', 'gravityview')); |
|
218 | + |
|
219 | + // If empty (null or empty string), add top-level menu |
|
220 | + if (empty($parent_slug)) { |
|
221 | + add_menu_page( |
|
222 | + $menu_title, |
|
223 | + $menu_title, |
|
224 | + 'create_users', |
|
225 | + $menu_slug, |
|
226 | + [$this, 'print_auth_screen'], |
|
227 | + $this->config->get_setting('menu/icon_url', ''), |
|
228 | + $this->config->get_setting('menu/position', null) |
|
229 | + ); |
|
230 | + |
|
231 | + return; |
|
232 | + } |
|
233 | + |
|
234 | + add_submenu_page( |
|
235 | + $parent_slug, |
|
236 | + $menu_title, |
|
237 | + $menu_title, |
|
238 | + 'create_users', |
|
239 | + $menu_slug, |
|
240 | + [$this, 'print_auth_screen'], |
|
241 | + $this->config->get_setting('menu/position', null) |
|
242 | + ); |
|
243 | + } |
|
244 | + |
|
245 | + /** |
|
246 | + * Is this a login screen and should TrustedLogin override the login screen for the current namespace? |
|
247 | + * |
|
248 | + * @return bool |
|
249 | + */ |
|
250 | + private function is_login_screen() |
|
251 | + { |
|
252 | + return did_action('login_init') && isset($_GET['ns']) && $_GET['ns'] === $this->config->ns(); |
|
253 | + } |
|
254 | + |
|
255 | + /** |
|
256 | + * If the current request is a valid login screen override, print the TrustedLogin request screen. |
|
257 | + * |
|
258 | + * @return void |
|
259 | + */ |
|
260 | + public function maybe_print_request_screen() |
|
261 | + { |
|
262 | + if (!$this->is_login_screen()) { |
|
263 | + return; |
|
264 | + } |
|
265 | + |
|
266 | + // Once logged-in, take user back to auth request screen. |
|
267 | + if (!is_user_logged_in()) { |
|
268 | + $_REQUEST['redirect_to'] = site_url(add_query_arg([])); |
|
269 | + |
|
270 | + return; |
|
271 | + } |
|
272 | + |
|
273 | + if (!current_user_can('create_users')) { |
|
274 | + return; |
|
275 | + } |
|
276 | + |
|
277 | + $this->print_request_screen(); |
|
278 | + } |
|
279 | + |
|
280 | + public function print_request_screen() |
|
281 | + { |
|
282 | + global $interim_login, $wp_version; |
|
283 | + |
|
284 | + // Don't output a "← Back to site" link on the login page |
|
285 | + $interim_login = true; |
|
286 | + |
|
287 | + // The login_headertitle filter was deprecated in WP 5.2.0 for login_headertext |
|
288 | + if (version_compare($wp_version, '5.2.0', '<')) { |
|
289 | + add_filter('login_headertitle', '__return_empty_string'); |
|
290 | + } else { |
|
291 | + add_filter('login_headertext', '__return_empty_string'); |
|
292 | + } |
|
293 | + |
|
294 | + add_filter('login_headerurl', function () { |
|
295 | + return $this->config->get_setting('vendor/website'); |
|
296 | + }); |
|
297 | + |
|
298 | + login_header(); |
|
299 | + |
|
300 | + wp_enqueue_style('common'); |
|
301 | + |
|
302 | + wp_add_inline_style('common', $this->get_login_inline_css()); |
|
303 | + |
|
304 | + echo $this->get_auth_screen(); |
|
305 | + |
|
306 | + login_footer(); |
|
307 | + |
|
308 | + exit(); |
|
309 | + } |
|
310 | + |
|
311 | + /** |
|
312 | + * Returns inline CSS overrides for the `common` CSS dependency. |
|
313 | + * |
|
314 | + * @since 1.0.0 |
|
315 | + * |
|
316 | + * @return string |
|
317 | + */ |
|
318 | + private function get_login_inline_css() |
|
319 | + { |
|
320 | + return ' |
|
321 | 321 | #login { |
322 | 322 | width: auto; |
323 | 323 | } |
@@ -332,79 +332,79 @@ discard block |
||
332 | 332 | background-size: contain!important; |
333 | 333 | } |
334 | 334 | '; |
335 | - } |
|
335 | + } |
|
336 | 336 | |
337 | - /** |
|
338 | - * Outputs the TrustedLogin authorization screen. |
|
339 | - * |
|
340 | - * @since 1.0.0 |
|
341 | - * |
|
342 | - * @return void |
|
343 | - */ |
|
344 | - public function print_auth_screen() |
|
345 | - { |
|
346 | - echo $this->get_auth_screen(); |
|
347 | - } |
|
337 | + /** |
|
338 | + * Outputs the TrustedLogin authorization screen. |
|
339 | + * |
|
340 | + * @since 1.0.0 |
|
341 | + * |
|
342 | + * @return void |
|
343 | + */ |
|
344 | + public function print_auth_screen() |
|
345 | + { |
|
346 | + echo $this->get_auth_screen(); |
|
347 | + } |
|
348 | 348 | |
349 | - public function get_auth_header_html() |
|
350 | - { |
|
351 | - $support_users = $this->support_user->get_all(); |
|
349 | + public function get_auth_header_html() |
|
350 | + { |
|
351 | + $support_users = $this->support_user->get_all(); |
|
352 | 352 | |
353 | - if (empty($support_users)) { |
|
354 | - return ''; |
|
355 | - } |
|
353 | + if (empty($support_users)) { |
|
354 | + return ''; |
|
355 | + } |
|
356 | 356 | |
357 | - $support_user = $support_users[0]; |
|
357 | + $support_user = $support_users[0]; |
|
358 | 358 | |
359 | - $_user_creator_id = get_user_option($this->support_user->created_by_meta_key, $support_user->ID); |
|
360 | - $_user_creator = $_user_creator_id ? get_user_by('id', $_user_creator_id) : false; |
|
359 | + $_user_creator_id = get_user_option($this->support_user->created_by_meta_key, $support_user->ID); |
|
360 | + $_user_creator = $_user_creator_id ? get_user_by('id', $_user_creator_id) : false; |
|
361 | 361 | |
362 | - $unknown_user_text = sprintf(esc_html__('Unknown (User #%d)', 'gravityview'), $_user_creator_id); |
|
362 | + $unknown_user_text = sprintf(esc_html__('Unknown (User #%d)', 'gravityview'), $_user_creator_id); |
|
363 | 363 | |
364 | - $auth_meta = ($_user_creator && $_user_creator->exists()) ? esc_html($_user_creator->display_name) : $unknown_user_text; |
|
364 | + $auth_meta = ($_user_creator && $_user_creator->exists()) ? esc_html($_user_creator->display_name) : $unknown_user_text; |
|
365 | 365 | |
366 | - $revoke_url = $this->support_user->get_revoke_url($support_user); |
|
366 | + $revoke_url = $this->support_user->get_revoke_url($support_user); |
|
367 | 367 | |
368 | - $template = ' |
|
368 | + $template = ' |
|
369 | 369 | {{revoke_access_button}} |
370 | 370 | <h3>{{display_name}}</h3> |
371 | 371 | <span class="tl-{{ns}}-auth__meta">{{auth_meta}}</span>'; |
372 | 372 | |
373 | - $content = [ |
|
374 | - 'display_name' => $support_user->display_name, |
|
375 | - 'revoke_access_button' => sprintf('<a href="%s" class="button button-danger alignright">%s</a>', $revoke_url, esc_html__('Revoke Access', 'gravityview')), |
|
376 | - 'auth_meta' => sprintf('Created 1 day ago by %s', $auth_meta), |
|
377 | - ]; |
|
378 | - |
|
379 | - return $this->prepare_output($template, $content); |
|
380 | - } |
|
381 | - |
|
382 | - /** |
|
383 | - * Output the contents of the Auth Link Page in wp-admin. |
|
384 | - * |
|
385 | - * @since 1.0.0 |
|
386 | - * |
|
387 | - * @return string HTML of the Auth screen |
|
388 | - */ |
|
389 | - public function get_auth_screen() |
|
390 | - { |
|
391 | - wp_enqueue_style('trustedlogin-'.$this->config->ns()); |
|
392 | - |
|
393 | - $content = [ |
|
394 | - 'ns' => $this->config->ns(), |
|
395 | - 'has_access_class' => $this->support_user->get_all() ? 'has-access' : 'grant-access', |
|
396 | - 'notices' => $this->get_notices_html(), |
|
397 | - 'header' => $this->get_header_html(), |
|
398 | - 'intro' => $this->get_intro(), |
|
399 | - 'auth_header' => $this->get_auth_header_html(), |
|
400 | - 'details' => $this->get_details_html(), |
|
401 | - 'button' => $this->generate_button('size=hero&class=authlink button-primary', false), |
|
402 | - 'secured_by_trustedlogin' => '<span class="trustedlogin-logo-large"></span>'.esc_html__('Secured by TrustedLogin', 'gravityview'), |
|
403 | - 'footer' => $this->get_footer_html(), |
|
404 | - 'reference' => $this->get_reference_html(), |
|
405 | - ]; |
|
406 | - |
|
407 | - $auth_screen_template = ' |
|
373 | + $content = [ |
|
374 | + 'display_name' => $support_user->display_name, |
|
375 | + 'revoke_access_button' => sprintf('<a href="%s" class="button button-danger alignright">%s</a>', $revoke_url, esc_html__('Revoke Access', 'gravityview')), |
|
376 | + 'auth_meta' => sprintf('Created 1 day ago by %s', $auth_meta), |
|
377 | + ]; |
|
378 | + |
|
379 | + return $this->prepare_output($template, $content); |
|
380 | + } |
|
381 | + |
|
382 | + /** |
|
383 | + * Output the contents of the Auth Link Page in wp-admin. |
|
384 | + * |
|
385 | + * @since 1.0.0 |
|
386 | + * |
|
387 | + * @return string HTML of the Auth screen |
|
388 | + */ |
|
389 | + public function get_auth_screen() |
|
390 | + { |
|
391 | + wp_enqueue_style('trustedlogin-'.$this->config->ns()); |
|
392 | + |
|
393 | + $content = [ |
|
394 | + 'ns' => $this->config->ns(), |
|
395 | + 'has_access_class' => $this->support_user->get_all() ? 'has-access' : 'grant-access', |
|
396 | + 'notices' => $this->get_notices_html(), |
|
397 | + 'header' => $this->get_header_html(), |
|
398 | + 'intro' => $this->get_intro(), |
|
399 | + 'auth_header' => $this->get_auth_header_html(), |
|
400 | + 'details' => $this->get_details_html(), |
|
401 | + 'button' => $this->generate_button('size=hero&class=authlink button-primary', false), |
|
402 | + 'secured_by_trustedlogin' => '<span class="trustedlogin-logo-large"></span>'.esc_html__('Secured by TrustedLogin', 'gravityview'), |
|
403 | + 'footer' => $this->get_footer_html(), |
|
404 | + 'reference' => $this->get_reference_html(), |
|
405 | + ]; |
|
406 | + |
|
407 | + $auth_screen_template = ' |
|
408 | 408 | <div class="tl-{{ns}}-auth tl-{{ns}}-{{has_access_class}}"> |
409 | 409 | {{header}} |
410 | 410 | <section class="tl-{{ns}}-auth__body"> |
@@ -430,105 +430,105 @@ discard block |
||
430 | 430 | </footer> |
431 | 431 | </div>'; |
432 | 432 | |
433 | - /** |
|
434 | - * Filter trustedlogin/{ns}/template/auth. |
|
435 | - * |
|
436 | - * @param string $output_template The Auth form HTML |
|
437 | - */ |
|
438 | - $auth_screen_template = apply_filters('trustedlogin/'.$this->config->ns().'/template/auth', $auth_screen_template); |
|
433 | + /** |
|
434 | + * Filter trustedlogin/{ns}/template/auth. |
|
435 | + * |
|
436 | + * @param string $output_template The Auth form HTML |
|
437 | + */ |
|
438 | + $auth_screen_template = apply_filters('trustedlogin/'.$this->config->ns().'/template/auth', $auth_screen_template); |
|
439 | 439 | |
440 | - $output = $this->prepare_output($auth_screen_template, $content); |
|
440 | + $output = $this->prepare_output($auth_screen_template, $content); |
|
441 | 441 | |
442 | - return $output; |
|
443 | - } |
|
442 | + return $output; |
|
443 | + } |
|
444 | 444 | |
445 | - private function get_header_html() |
|
446 | - { |
|
447 | - if ($this->is_login_screen()) { |
|
448 | - return ''; |
|
449 | - } |
|
445 | + private function get_header_html() |
|
446 | + { |
|
447 | + if ($this->is_login_screen()) { |
|
448 | + return ''; |
|
449 | + } |
|
450 | 450 | |
451 | - $header_template = ' |
|
451 | + $header_template = ' |
|
452 | 452 | <header class="tl-{{ns}}-auth__header__top"> |
453 | 453 | <div class="tl-{{ns}}-auth__logo">{{logo}}</div> |
454 | 454 | </header>'; |
455 | 455 | |
456 | - $variables = [ |
|
457 | - 'ns' => $this->config->ns(), |
|
458 | - 'logo' => $this->get_logo_html(), |
|
459 | - ]; |
|
460 | - |
|
461 | - return $this->prepare_output($header_template, $variables); |
|
462 | - } |
|
463 | - |
|
464 | - /** |
|
465 | - * Shows the current site URL and, if passed as $_GET['ref'], a support reference ID. |
|
466 | - * |
|
467 | - * @return string |
|
468 | - */ |
|
469 | - private function get_reference_html() |
|
470 | - { |
|
471 | - if (!$this->is_login_screen()) { |
|
472 | - return ''; |
|
473 | - } |
|
474 | - |
|
475 | - $reference_id = Client::get_reference_id(); |
|
476 | - |
|
477 | - if (null === $reference_id) { |
|
478 | - return ''; |
|
479 | - } |
|
480 | - |
|
481 | - $template = '<div class="tl-{{ns}}-auth__ref"><p><span class="tl-{{ns}}-auth_ref__id">{{reference_text}}</span></p></div>'; |
|
482 | - |
|
483 | - $content = [ |
|
484 | - 'reference_text' => sprintf(esc_html__('Reference #%s', 'gravityview'), $reference_id), |
|
485 | - 'ns' => $this->config->ns(), |
|
486 | - 'site_url' => esc_html(str_replace(['https://', 'http://'], '', get_site_url())), |
|
487 | - ]; |
|
488 | - |
|
489 | - return $this->prepare_output($template, $content); |
|
490 | - } |
|
491 | - |
|
492 | - private function get_intro() |
|
493 | - { |
|
494 | - $has_access = $this->support_user->get_all(); |
|
495 | - |
|
496 | - if ($has_access) { |
|
497 | - foreach ($has_access as $access) { |
|
498 | - // translators: %1$s is replaced with the name of the software developer (e.g. "Acme Widgets"). %2$s is the amount of time remaining for access ("1 week") |
|
499 | - $intro = sprintf(esc_html__('%1$s has site access that expires in %2$s.', 'gravityview'), '<a href="'.esc_url($this->config->get_setting('vendor/website')).'" target="_blank" rel="noopener noreferrer">'.$this->config->get_setting('vendor/title').'</a>', str_replace(' ', ' ', $this->support_user->get_expiration($access, true, false))); |
|
500 | - } |
|
501 | - |
|
502 | - return $intro; |
|
503 | - } |
|
504 | - |
|
505 | - if ($this->is_login_screen()) { |
|
506 | - // translators: %1$s is replaced with the name of the software developer (e.g. "Acme Widgets") |
|
507 | - $intro = sprintf(esc_html__('%1$s would like support access to this site.', 'gravityview'), '<a href="'.esc_url($this->config->get_setting('vendor/website')).'">'.$this->config->get_display_name().'</a>'); |
|
508 | - } else { |
|
509 | - // translators: %1$s is replaced with the name of the software developer (e.g. "Acme Widgets") |
|
510 | - $intro = sprintf(esc_html__('Grant %1$s access to this site.', 'gravityview'), '<a href="'.esc_url($this->config->get_setting('vendor/website')).'">'.$this->config->get_display_name().'</a>'); |
|
511 | - } |
|
512 | - |
|
513 | - return $intro; |
|
514 | - } |
|
515 | - |
|
516 | - private function get_details_html() |
|
517 | - { |
|
518 | - $has_access = $this->support_user->get_all(); |
|
519 | - |
|
520 | - // Has access |
|
521 | - if ($has_access) { |
|
522 | - $output_template = ''; |
|
523 | - $output_template .= '{{users_table}}'; |
|
524 | - $content = [ |
|
525 | - 'users_table' => $this->output_support_users(false, ['current_url' => true]), |
|
526 | - ]; |
|
527 | - |
|
528 | - return $this->prepare_output($output_template, $content, false); |
|
529 | - } |
|
530 | - |
|
531 | - $output_template = ' |
|
456 | + $variables = [ |
|
457 | + 'ns' => $this->config->ns(), |
|
458 | + 'logo' => $this->get_logo_html(), |
|
459 | + ]; |
|
460 | + |
|
461 | + return $this->prepare_output($header_template, $variables); |
|
462 | + } |
|
463 | + |
|
464 | + /** |
|
465 | + * Shows the current site URL and, if passed as $_GET['ref'], a support reference ID. |
|
466 | + * |
|
467 | + * @return string |
|
468 | + */ |
|
469 | + private function get_reference_html() |
|
470 | + { |
|
471 | + if (!$this->is_login_screen()) { |
|
472 | + return ''; |
|
473 | + } |
|
474 | + |
|
475 | + $reference_id = Client::get_reference_id(); |
|
476 | + |
|
477 | + if (null === $reference_id) { |
|
478 | + return ''; |
|
479 | + } |
|
480 | + |
|
481 | + $template = '<div class="tl-{{ns}}-auth__ref"><p><span class="tl-{{ns}}-auth_ref__id">{{reference_text}}</span></p></div>'; |
|
482 | + |
|
483 | + $content = [ |
|
484 | + 'reference_text' => sprintf(esc_html__('Reference #%s', 'gravityview'), $reference_id), |
|
485 | + 'ns' => $this->config->ns(), |
|
486 | + 'site_url' => esc_html(str_replace(['https://', 'http://'], '', get_site_url())), |
|
487 | + ]; |
|
488 | + |
|
489 | + return $this->prepare_output($template, $content); |
|
490 | + } |
|
491 | + |
|
492 | + private function get_intro() |
|
493 | + { |
|
494 | + $has_access = $this->support_user->get_all(); |
|
495 | + |
|
496 | + if ($has_access) { |
|
497 | + foreach ($has_access as $access) { |
|
498 | + // translators: %1$s is replaced with the name of the software developer (e.g. "Acme Widgets"). %2$s is the amount of time remaining for access ("1 week") |
|
499 | + $intro = sprintf(esc_html__('%1$s has site access that expires in %2$s.', 'gravityview'), '<a href="'.esc_url($this->config->get_setting('vendor/website')).'" target="_blank" rel="noopener noreferrer">'.$this->config->get_setting('vendor/title').'</a>', str_replace(' ', ' ', $this->support_user->get_expiration($access, true, false))); |
|
500 | + } |
|
501 | + |
|
502 | + return $intro; |
|
503 | + } |
|
504 | + |
|
505 | + if ($this->is_login_screen()) { |
|
506 | + // translators: %1$s is replaced with the name of the software developer (e.g. "Acme Widgets") |
|
507 | + $intro = sprintf(esc_html__('%1$s would like support access to this site.', 'gravityview'), '<a href="'.esc_url($this->config->get_setting('vendor/website')).'">'.$this->config->get_display_name().'</a>'); |
|
508 | + } else { |
|
509 | + // translators: %1$s is replaced with the name of the software developer (e.g. "Acme Widgets") |
|
510 | + $intro = sprintf(esc_html__('Grant %1$s access to this site.', 'gravityview'), '<a href="'.esc_url($this->config->get_setting('vendor/website')).'">'.$this->config->get_display_name().'</a>'); |
|
511 | + } |
|
512 | + |
|
513 | + return $intro; |
|
514 | + } |
|
515 | + |
|
516 | + private function get_details_html() |
|
517 | + { |
|
518 | + $has_access = $this->support_user->get_all(); |
|
519 | + |
|
520 | + // Has access |
|
521 | + if ($has_access) { |
|
522 | + $output_template = ''; |
|
523 | + $output_template .= '{{users_table}}'; |
|
524 | + $content = [ |
|
525 | + 'users_table' => $this->output_support_users(false, ['current_url' => true]), |
|
526 | + ]; |
|
527 | + |
|
528 | + return $this->prepare_output($output_template, $content, false); |
|
529 | + } |
|
530 | + |
|
531 | + $output_template = ' |
|
532 | 532 | <p><span class="dashicons dashicons-info-outline dashicons--small"></span> This will allow <strong>{{name}}</strong> to:</p> |
533 | 533 | <div class="tl-{{ns}}-auth__roles"> |
534 | 534 | <h2><span class="dashicons dashicons-admin-users dashicons--large"></span>{{roles_summary}}</h2> |
@@ -539,631 +539,631 @@ discard block |
||
539 | 539 | </div> |
540 | 540 | '; |
541 | 541 | |
542 | - // translators: %1$s and %3$s are replaced with HTML tags. %2$s is the amount of time that the login will be active for (e.g. "1 week") |
|
543 | - $expire_summary = sprintf(esc_html__('Access this site for %s.', 'gravityview'), '<strong>'.human_time_diff(0, $this->config->get_setting('decay')).'</strong>'); |
|
544 | - $expire_desc = '<small>'.sprintf(esc_html__('Access auto-expires in %s. You may revoke access at any time.', 'gravityview'), human_time_diff(0, $this->config->get_setting('decay'))).'</small>'; |
|
545 | - |
|
546 | - $ns = $this->config->ns(); |
|
547 | - $cloned_role = translate_user_role(ucfirst($this->config->get_setting('role'))); |
|
548 | - |
|
549 | - if (array_filter($this->config->get_setting('caps'), [$this->config, 'is_not_null'])) { |
|
550 | - $roles_summary = sprintf(esc_html__('Create a user with a role similar to %s.', 'gravityview'), '<strong>'.$cloned_role.'</strong>'); |
|
551 | - $roles_summary .= sprintf('<small class="tl-'.$ns.'-toggle" data-toggle=".tl-'.$ns.'-auth__role-container">%s <span class="dashicons dashicons--small dashicons-arrow-down-alt2"></span></small>', esc_html__('View role capabilities', 'gravityview')); |
|
552 | - } else { |
|
553 | - $roles_summary = sprintf(esc_html__('Create a user with a role of %s.', 'gravityview'), '<strong>'.$cloned_role.'</strong>'); |
|
554 | - } |
|
555 | - |
|
556 | - $content = [ |
|
557 | - 'ns' => $ns, |
|
558 | - 'name' => $this->config->get_display_name(), |
|
559 | - 'expire_summary' => $expire_summary, |
|
560 | - 'expire_desc' => $expire_desc, |
|
561 | - 'roles_summary' => $roles_summary, |
|
562 | - 'caps' => $this->get_caps_html(), |
|
563 | - ]; |
|
564 | - |
|
565 | - return $this->prepare_output($output_template, $content); |
|
566 | - } |
|
567 | - |
|
568 | - /** |
|
569 | - * Get role capabilities HTML the Auth form. |
|
570 | - * |
|
571 | - * @return string Empty string if there are no caps defined. Otherwise, HTML of caps in lists. |
|
572 | - */ |
|
573 | - private function get_caps_html() |
|
574 | - { |
|
575 | - $added = $this->config->get_setting('caps/add'); |
|
576 | - $removed = $this->config->get_setting('caps/remove'); |
|
577 | - |
|
578 | - $caps = ''; |
|
579 | - $caps .= $this->get_caps_section($added, __('Additional capabilities:', 'gravityview'), 'dashicons-yes-alt'); |
|
580 | - $caps .= $this->get_caps_section($removed, __('Removed capabilities:', 'gravityview'), 'dashicons-dismiss'); |
|
581 | - |
|
582 | - if (empty($caps)) { |
|
583 | - return $caps; |
|
584 | - } |
|
585 | - |
|
586 | - return '<div class="tl-'.$this->config->ns().'-auth__role-container hidden">'.$caps.'</div>'; |
|
587 | - } |
|
588 | - |
|
589 | - /** |
|
590 | - * Generate additional/removed capabilities sections. |
|
591 | - * |
|
592 | - * @param array $caps_array Associative array of cap => reason why cap is set |
|
593 | - * @param string $heading Text to show for the heading of the caps section |
|
594 | - * @param string $dashicon CSS class for the specific dashicon |
|
595 | - * |
|
596 | - * @return string |
|
597 | - */ |
|
598 | - private function get_caps_section($caps_array, $heading = '', $dashicon = '') |
|
599 | - { |
|
600 | - $caps_array = array_filter((array) $caps_array, [$this->config, 'is_not_null']); |
|
601 | - |
|
602 | - if (empty($caps_array)) { |
|
603 | - return ''; |
|
604 | - } |
|
605 | - |
|
606 | - $output = ''; |
|
607 | - $output .= '<div>'; |
|
608 | - $output .= '<h3>'.esc_html($heading).'</h3>'; |
|
609 | - $output .= '<ul>'; |
|
610 | - |
|
611 | - foreach ((array) $caps_array as $cap => $reason) { |
|
612 | - $dashicon = '<span class="dashicons '.esc_attr($dashicon).' dashicons--small"></span>'; |
|
613 | - $reason = empty($reason) ? '' : '<small>'.esc_html($reason).'</small>'; |
|
614 | - $output .= sprintf('<li>%s<span class="code">%s</span>%s</li>', $dashicon, esc_html($cap), $reason); |
|
615 | - } |
|
616 | - |
|
617 | - $output .= '</ul>'; |
|
618 | - $output .= '</div>'; |
|
619 | - |
|
620 | - return $output; |
|
621 | - } |
|
622 | - |
|
623 | - /** |
|
624 | - * Generates HTML for notices about current server environment perhaps not being accessible. |
|
625 | - * |
|
626 | - * @return string |
|
627 | - */ |
|
628 | - private function get_notices_html() |
|
629 | - { |
|
630 | - if (!function_exists('wp_get_environment_type')) { |
|
631 | - return ''; |
|
632 | - } |
|
633 | - |
|
634 | - if (in_array(wp_get_environment_type(), ['staging', 'production'], true)) { |
|
635 | - return ''; |
|
636 | - } |
|
637 | - |
|
638 | - if (defined('TRUSTEDLOGIN_DISABLE_LOCAL_NOTICE') && TRUSTEDLOGIN_DISABLE_LOCAL_NOTICE) { |
|
639 | - return ''; |
|
640 | - } |
|
641 | - |
|
642 | - $notice_template = ' |
|
542 | + // translators: %1$s and %3$s are replaced with HTML tags. %2$s is the amount of time that the login will be active for (e.g. "1 week") |
|
543 | + $expire_summary = sprintf(esc_html__('Access this site for %s.', 'gravityview'), '<strong>'.human_time_diff(0, $this->config->get_setting('decay')).'</strong>'); |
|
544 | + $expire_desc = '<small>'.sprintf(esc_html__('Access auto-expires in %s. You may revoke access at any time.', 'gravityview'), human_time_diff(0, $this->config->get_setting('decay'))).'</small>'; |
|
545 | + |
|
546 | + $ns = $this->config->ns(); |
|
547 | + $cloned_role = translate_user_role(ucfirst($this->config->get_setting('role'))); |
|
548 | + |
|
549 | + if (array_filter($this->config->get_setting('caps'), [$this->config, 'is_not_null'])) { |
|
550 | + $roles_summary = sprintf(esc_html__('Create a user with a role similar to %s.', 'gravityview'), '<strong>'.$cloned_role.'</strong>'); |
|
551 | + $roles_summary .= sprintf('<small class="tl-'.$ns.'-toggle" data-toggle=".tl-'.$ns.'-auth__role-container">%s <span class="dashicons dashicons--small dashicons-arrow-down-alt2"></span></small>', esc_html__('View role capabilities', 'gravityview')); |
|
552 | + } else { |
|
553 | + $roles_summary = sprintf(esc_html__('Create a user with a role of %s.', 'gravityview'), '<strong>'.$cloned_role.'</strong>'); |
|
554 | + } |
|
555 | + |
|
556 | + $content = [ |
|
557 | + 'ns' => $ns, |
|
558 | + 'name' => $this->config->get_display_name(), |
|
559 | + 'expire_summary' => $expire_summary, |
|
560 | + 'expire_desc' => $expire_desc, |
|
561 | + 'roles_summary' => $roles_summary, |
|
562 | + 'caps' => $this->get_caps_html(), |
|
563 | + ]; |
|
564 | + |
|
565 | + return $this->prepare_output($output_template, $content); |
|
566 | + } |
|
567 | + |
|
568 | + /** |
|
569 | + * Get role capabilities HTML the Auth form. |
|
570 | + * |
|
571 | + * @return string Empty string if there are no caps defined. Otherwise, HTML of caps in lists. |
|
572 | + */ |
|
573 | + private function get_caps_html() |
|
574 | + { |
|
575 | + $added = $this->config->get_setting('caps/add'); |
|
576 | + $removed = $this->config->get_setting('caps/remove'); |
|
577 | + |
|
578 | + $caps = ''; |
|
579 | + $caps .= $this->get_caps_section($added, __('Additional capabilities:', 'gravityview'), 'dashicons-yes-alt'); |
|
580 | + $caps .= $this->get_caps_section($removed, __('Removed capabilities:', 'gravityview'), 'dashicons-dismiss'); |
|
581 | + |
|
582 | + if (empty($caps)) { |
|
583 | + return $caps; |
|
584 | + } |
|
585 | + |
|
586 | + return '<div class="tl-'.$this->config->ns().'-auth__role-container hidden">'.$caps.'</div>'; |
|
587 | + } |
|
588 | + |
|
589 | + /** |
|
590 | + * Generate additional/removed capabilities sections. |
|
591 | + * |
|
592 | + * @param array $caps_array Associative array of cap => reason why cap is set |
|
593 | + * @param string $heading Text to show for the heading of the caps section |
|
594 | + * @param string $dashicon CSS class for the specific dashicon |
|
595 | + * |
|
596 | + * @return string |
|
597 | + */ |
|
598 | + private function get_caps_section($caps_array, $heading = '', $dashicon = '') |
|
599 | + { |
|
600 | + $caps_array = array_filter((array) $caps_array, [$this->config, 'is_not_null']); |
|
601 | + |
|
602 | + if (empty($caps_array)) { |
|
603 | + return ''; |
|
604 | + } |
|
605 | + |
|
606 | + $output = ''; |
|
607 | + $output .= '<div>'; |
|
608 | + $output .= '<h3>'.esc_html($heading).'</h3>'; |
|
609 | + $output .= '<ul>'; |
|
610 | + |
|
611 | + foreach ((array) $caps_array as $cap => $reason) { |
|
612 | + $dashicon = '<span class="dashicons '.esc_attr($dashicon).' dashicons--small"></span>'; |
|
613 | + $reason = empty($reason) ? '' : '<small>'.esc_html($reason).'</small>'; |
|
614 | + $output .= sprintf('<li>%s<span class="code">%s</span>%s</li>', $dashicon, esc_html($cap), $reason); |
|
615 | + } |
|
616 | + |
|
617 | + $output .= '</ul>'; |
|
618 | + $output .= '</div>'; |
|
619 | + |
|
620 | + return $output; |
|
621 | + } |
|
622 | + |
|
623 | + /** |
|
624 | + * Generates HTML for notices about current server environment perhaps not being accessible. |
|
625 | + * |
|
626 | + * @return string |
|
627 | + */ |
|
628 | + private function get_notices_html() |
|
629 | + { |
|
630 | + if (!function_exists('wp_get_environment_type')) { |
|
631 | + return ''; |
|
632 | + } |
|
633 | + |
|
634 | + if (in_array(wp_get_environment_type(), ['staging', 'production'], true)) { |
|
635 | + return ''; |
|
636 | + } |
|
637 | + |
|
638 | + if (defined('TRUSTEDLOGIN_DISABLE_LOCAL_NOTICE') && TRUSTEDLOGIN_DISABLE_LOCAL_NOTICE) { |
|
639 | + return ''; |
|
640 | + } |
|
641 | + |
|
642 | + $notice_template = ' |
|
643 | 643 | <div class="inline notice notice-alt notice-warning"> |
644 | 644 | <h3>{{local_site}}</h3> |
645 | 645 | <p>{{need_access}} <a href="{{about_live_access_url}}" target="_blank" rel="noopener noreferrer">{{learn_more}}</a></p> |
646 | 646 | </div>'; |
647 | 647 | |
648 | - $content = [ |
|
649 | - 'local_site' => sprintf(esc_html__('%s support may not be able to access this site.', 'gravityview'), $this->config->get_setting('vendor/title')), |
|
650 | - 'need_access' => esc_html__('This website is running in a local development environment. To provide support, we must be able to access your site using a publicly-accessible URL.', 'gravityview'), |
|
651 | - 'about_live_access_url' => esc_url($this->config->get_setting('vendor/about_live_access_url', self::ABOUT_LIVE_ACCESS_URL)), |
|
652 | - 'learn_more' => esc_html__('Learn more.', 'gravityview'), |
|
653 | - ]; |
|
654 | - |
|
655 | - return $this->prepare_output($notice_template, $content); |
|
656 | - } |
|
657 | - |
|
658 | - /** |
|
659 | - * @return string |
|
660 | - */ |
|
661 | - private function get_logo_html() |
|
662 | - { |
|
663 | - $logo_url = $this->config->get_setting('vendor/logo_url'); |
|
664 | - |
|
665 | - $logo_output = ''; |
|
666 | - |
|
667 | - if (!empty($logo_url)) { |
|
668 | - $logo_output = sprintf( |
|
669 | - '<a href="%1$s" title="%2$s" target="_blank" rel="noreferrer noopener"><img src="%3$s" alt="%4$s" /></a>', |
|
670 | - esc_url($this->config->get_setting('vendor/website')), |
|
671 | - // translators: %s is replaced with the name of the software developer (e.g. "Acme Widgets") |
|
672 | - sprintf('Visit the %s website (opens in a new tab)', $this->config->get_setting('vendor/title')), |
|
673 | - esc_attr($this->config->get_setting('vendor/logo_url')), |
|
674 | - esc_attr($this->config->get_setting('vendor/title')) |
|
675 | - ); |
|
676 | - } |
|
677 | - |
|
678 | - return $logo_output; |
|
679 | - } |
|
680 | - |
|
681 | - /** |
|
682 | - * Returns the HTML for the footer in the Auth form. |
|
683 | - * |
|
684 | - * @return string |
|
685 | - */ |
|
686 | - private function get_footer_html() |
|
687 | - { |
|
688 | - $support_url = $this->config->get_setting('vendor/support_url'); |
|
689 | - |
|
690 | - if ($reference_id = Client::get_reference_id()) { |
|
691 | - $support_args = [ |
|
692 | - 'tl' => Client::VERSION, |
|
693 | - 'ref' => $reference_id, |
|
694 | - 'ns' => $this->config->ns(), |
|
695 | - ]; |
|
696 | - |
|
697 | - $support_url = add_query_arg($support_args, $support_url); |
|
698 | - } |
|
699 | - |
|
700 | - $footer_links = [ |
|
701 | - esc_html__('Learn about TrustedLogin', 'gravityview') => self::ABOUT_TL_URL, |
|
702 | - sprintf('Visit %s support', $this->config->get_setting('vendor/title')) => $support_url, |
|
703 | - ]; |
|
704 | - |
|
705 | - /** |
|
706 | - * Filter trustedlogin/template/auth/footer_links. |
|
707 | - * |
|
708 | - * Used to add/remove Footer Links on grantlink page |
|
709 | - * |
|
710 | - * @since 1.0.0 |
|
711 | - * |
|
712 | - * @param array Array of links to show in auth footer (Key is anchor text; Value is URL) |
|
713 | - **/ |
|
714 | - $footer_links = apply_filters('trustedlogin/'.$this->config->ns().'/template/auth/footer_links', $footer_links); |
|
715 | - |
|
716 | - $footer_links_output = ''; |
|
717 | - foreach ($footer_links as $text => $link) { |
|
718 | - $footer_links_output .= sprintf( |
|
719 | - '<li><a href="%1$s" target="_blank">%2$s</a></li>', |
|
720 | - esc_url($link), |
|
721 | - esc_html($text) |
|
722 | - ); |
|
723 | - } |
|
724 | - |
|
725 | - $footer_output = ''; |
|
726 | - if (!empty($footer_links_output)) { |
|
727 | - $footer_output = sprintf('<ul>%1$s</ul>', $footer_links_output); |
|
728 | - } |
|
729 | - |
|
730 | - return $footer_output; |
|
731 | - } |
|
732 | - |
|
733 | - private function prepare_output($template, $content, $wp_kses = true) |
|
734 | - { |
|
735 | - $output_html = $template; |
|
736 | - |
|
737 | - foreach ($content as $key => $value) { |
|
738 | - $output_html = str_replace('{{'.$key.'}}', $value, $output_html); |
|
739 | - } |
|
740 | - |
|
741 | - if ($wp_kses) { |
|
742 | - |
|
743 | - // Allow SVGs for logos |
|
744 | - $allowed_protocols = wp_allowed_protocols(); |
|
745 | - $allowed_protocols[] = 'data'; |
|
746 | - |
|
747 | - $output_html = wp_kses( |
|
748 | - $output_html, |
|
749 | - [ |
|
750 | - 'a' => [ |
|
751 | - 'class' => [], |
|
752 | - 'id' => [], |
|
753 | - 'href' => [], |
|
754 | - 'title' => [], |
|
755 | - 'rel' => [], |
|
756 | - 'target' => [], |
|
757 | - 'data-toggle' => [], |
|
758 | - 'data-access' => [], |
|
759 | - ], |
|
760 | - 'img' => [ |
|
761 | - 'class' => [], |
|
762 | - 'id' => [], |
|
763 | - 'src' => [], |
|
764 | - 'href' => [], |
|
765 | - 'alt' => [], |
|
766 | - 'title' => [], |
|
767 | - ], |
|
768 | - 'span' => [ |
|
769 | - 'class' => [], |
|
770 | - 'id' => [], |
|
771 | - 'title' => [], |
|
772 | - 'data-toggle' => [], |
|
773 | - 'style' => [], |
|
774 | - ], |
|
775 | - 'label' => ['class' => [], 'id' => [], 'for' => []], |
|
776 | - 'code' => ['class' => [], 'id' => []], |
|
777 | - 'tt' => ['class' => [], 'id' => []], |
|
778 | - 'pre' => ['class' => [], 'id' => []], |
|
779 | - 'table' => ['class' => [], 'id' => []], |
|
780 | - 'thead' => [], |
|
781 | - 'tfoot' => [], |
|
782 | - 'td' => ['class' => [], 'id' => [], 'colspan' => []], |
|
783 | - 'th' => ['class' => [], 'id' => [], 'colspan' => [], 'scope' => []], |
|
784 | - 'ul' => ['class' => [], 'id' => []], |
|
785 | - 'li' => ['class' => [], 'id' => []], |
|
786 | - 'p' => ['class' => [], 'id' => []], |
|
787 | - 'h1' => ['class' => [], 'id' => []], |
|
788 | - 'h2' => ['class' => [], 'id' => []], |
|
789 | - 'h3' => ['class' => [], 'id' => [], 'style' => []], |
|
790 | - 'h4' => ['class' => [], 'id' => []], |
|
791 | - 'h5' => ['class' => [], 'id' => []], |
|
792 | - 'div' => ['class' => [], 'id' => [], 'aria-live' => [], 'style' => []], |
|
793 | - 'small' => ['class' => [], 'id' => [], 'data-toggle' => []], |
|
794 | - 'header' => ['class' => [], 'id' => []], |
|
795 | - 'footer' => ['class' => [], 'id' => []], |
|
796 | - 'section' => ['class' => [], 'id' => []], |
|
797 | - 'br' => [], |
|
798 | - 'strong' => [], |
|
799 | - 'em' => [], |
|
800 | - 'input' => [ |
|
801 | - 'class' => [], |
|
802 | - 'id' => [], |
|
803 | - 'type' => ['text'], |
|
804 | - 'value' => [], |
|
805 | - 'size' => [], |
|
806 | - 'aria-live' => [], |
|
807 | - 'aria-label' => [], |
|
808 | - 'style' => [], |
|
809 | - ], |
|
810 | - 'button' => [ |
|
811 | - 'class' => [], |
|
812 | - 'id' => [], |
|
813 | - 'aria-live' => [], |
|
814 | - 'style' => [], |
|
815 | - 'title' => [], |
|
816 | - ], |
|
817 | - ], |
|
818 | - $allowed_protocols |
|
819 | - ); |
|
820 | - } |
|
821 | - |
|
822 | - return normalize_whitespace($output_html); |
|
823 | - } |
|
824 | - |
|
825 | - /** |
|
826 | - * Output the TrustedLogin Button and required scripts. |
|
827 | - * |
|
828 | - * @since 1.0.0 |
|
829 | - * |
|
830 | - * @param array $atts {@see get_button()} for configuration array |
|
831 | - * @param bool $print Should results be printed and returned (true) or only returned (false) |
|
832 | - * |
|
833 | - * @return string the HTML output |
|
834 | - */ |
|
835 | - public function generate_button($atts = [], $print = true) |
|
836 | - { |
|
837 | - if (!current_user_can('create_users')) { |
|
838 | - return ''; |
|
839 | - } |
|
840 | - |
|
841 | - if (!wp_script_is('trustedlogin-'.$this->config->ns(), 'registered')) { |
|
842 | - $this->logging->log('JavaScript is not registered. Make sure `trustedlogin` handle is added to "no-conflict" plugin settings.', __METHOD__, 'error'); |
|
843 | - } |
|
844 | - |
|
845 | - if (!wp_style_is('trustedlogin-'.$this->config->ns(), 'registered')) { |
|
846 | - $this->logging->log('Style is not registered. Make sure `trustedlogin` handle is added to "no-conflict" plugin settings.', __METHOD__, 'error'); |
|
847 | - } |
|
848 | - |
|
849 | - wp_enqueue_style('trustedlogin-'.$this->config->ns()); |
|
850 | - |
|
851 | - $button_settings = [ |
|
852 | - 'vendor' => $this->config->get_setting('vendor'), |
|
853 | - 'ajaxurl' => admin_url('admin-ajax.php'), |
|
854 | - '_nonce' => wp_create_nonce('tl_nonce-'.get_current_user_id()), |
|
855 | - 'lang' => $this->translations(), |
|
856 | - 'debug' => $this->logging->is_enabled(), |
|
857 | - 'selector' => '.button-trustedlogin-'.$this->config->ns(), |
|
858 | - 'reference_id' => Client::get_reference_id(), |
|
859 | - 'query_string' => esc_url(remove_query_arg([ |
|
860 | - Endpoint::REVOKE_SUPPORT_QUERY_PARAM, |
|
861 | - '_wpnonce', |
|
862 | - ])), |
|
863 | - ]; |
|
864 | - |
|
865 | - // TODO: Add data to tl_obj when detecting that it's already been localized by another vendor |
|
866 | - wp_localize_script('trustedlogin-'.$this->config->ns(), 'tl_obj', $button_settings); |
|
867 | - |
|
868 | - wp_enqueue_script('trustedlogin-'.$this->config->ns()); |
|
869 | - |
|
870 | - $return = $this->get_button($atts); |
|
871 | - |
|
872 | - if ($print) { |
|
873 | - echo $return; |
|
874 | - } |
|
875 | - |
|
876 | - return $return; |
|
877 | - } |
|
878 | - |
|
879 | - /** |
|
880 | - * Generates HTML for a TrustedLogin Grant Access button. |
|
881 | - * |
|
882 | - * @param array $atts { |
|
883 | - * |
|
884 | - * @var string $text Button text to grant access. Sanitized using esc_html(). Default: "Grant %s Access" |
|
885 | - * (%s replaced with vendor/title setting) |
|
886 | - * @var string $exists_text Button text when vendor already has a support account. Sanitized using esc_html(). |
|
887 | - * Default: "Extend %s Access" (%s replaced with vendor/title setting) |
|
888 | - * @var string $size WordPress CSS button size. Options: 'small', 'normal', 'large', 'hero'. Default: "hero" |
|
889 | - * @var string $class CSS class added to the button. Default: "button-primary" |
|
890 | - * @var string $tag Tag used to display the button. Options: 'a', 'button', 'span'. Default: "a" |
|
891 | - * @var bool $powered_by Whether to display the TrustedLogin badge on the button. Default: true |
|
892 | - * @var string $support_url The URL to use as a backup if JavaScript fails or isn't available. Sanitized using |
|
893 | - * esc_url(). Default: `vendor/support_url` configuration setting URL. |
|
894 | - * } |
|
895 | - * |
|
896 | - * @return string |
|
897 | - */ |
|
898 | - public function get_button($atts = []) |
|
899 | - { |
|
900 | - $defaults = [ |
|
901 | - 'text' => sprintf(esc_html__('Grant %s Access', 'gravityview'), $this->config->get_display_name()), |
|
902 | - 'exists_text' => sprintf(esc_html__('Extend %s Access', 'gravityview'), $this->config->get_display_name(), ucwords(human_time_diff(time(), time() + $this->config->get_setting('decay')))), |
|
903 | - 'size' => 'hero', |
|
904 | - 'class' => 'button-primary', |
|
905 | - 'tag' => 'a', // "a", "button", "span" |
|
906 | - 'powered_by' => false, |
|
907 | - 'support_url' => $this->config->get_setting('vendor/support_url'), |
|
908 | - ]; |
|
909 | - |
|
910 | - $sizes = ['small', 'normal', 'large', 'hero']; |
|
911 | - |
|
912 | - $atts = wp_parse_args($atts, $defaults); |
|
913 | - |
|
914 | - switch ($atts['size']) { |
|
915 | - case '': |
|
916 | - $css_class = ''; |
|
917 | - break; |
|
918 | - case 'normal': |
|
919 | - $css_class = 'button'; |
|
920 | - break; |
|
921 | - default: |
|
922 | - if (!in_array($atts['size'], $sizes)) { |
|
923 | - $atts['size'] = 'hero'; |
|
924 | - } |
|
925 | - |
|
926 | - $css_class = 'button button-'.$atts['size']; |
|
927 | - } |
|
928 | - |
|
929 | - $_valid_tags = ['a', 'button', 'span']; |
|
930 | - |
|
931 | - if (!empty($atts['tag']) && in_array(strtolower($atts['tag']), $_valid_tags, true)) { |
|
932 | - $tag = $atts['tag']; |
|
933 | - } else { |
|
934 | - $tag = 'a'; |
|
935 | - } |
|
936 | - |
|
937 | - $data_atts = []; |
|
938 | - |
|
939 | - if ($this->support_user->get_all()) { |
|
940 | - $text = '<span class="dashicons dashicons-update-alt"></span>'.esc_html($atts['exists_text']); |
|
941 | - $href = admin_url('users.php?role='.$this->support_user->role->get_name()); |
|
942 | - $data_atts['access'] = 'extend'; |
|
943 | - } else { |
|
944 | - $text = esc_html($atts['text']); |
|
945 | - $href = $atts['support_url']; |
|
946 | - $data_atts['access'] = 'grant'; |
|
947 | - } |
|
948 | - |
|
949 | - $css_class = implode(' ', [$css_class, $atts['class']]); |
|
950 | - $css_class = trim($css_class); |
|
951 | - |
|
952 | - $data_string = ''; |
|
953 | - foreach ($data_atts as $key => $value) { |
|
954 | - $data_string .= sprintf(' data-%s="%s"', esc_attr($key), esc_attr($value)); |
|
955 | - } |
|
956 | - |
|
957 | - $powered_by = ''; |
|
958 | - if ($atts['powered_by']) { |
|
959 | - $powered_by = sprintf( |
|
960 | - '<small><span class="trustedlogin-logo"></span>%s</small>', |
|
961 | - esc_html__('Secured by TrustedLogin', 'gravityview') |
|
962 | - ); |
|
963 | - } |
|
964 | - |
|
965 | - $anchor_html = $text.$powered_by; |
|
966 | - |
|
967 | - return sprintf( |
|
968 | - '<%1$s href="%2$s" class="%3$s button-trustedlogin-%4$s" aria-role="button" %5$s>%6$s</%1$s>', |
|
969 | - /* %1$s */ |
|
970 | - $tag, |
|
971 | - /* %2$s */ |
|
972 | - esc_url($href), |
|
973 | - /* %3$s */ |
|
974 | - esc_attr($css_class), |
|
975 | - /* %4$s */ |
|
976 | - $this->config->ns(), |
|
977 | - /* %5$s */ |
|
978 | - $data_string, |
|
979 | - /* %6$s */ |
|
980 | - $anchor_html |
|
981 | - ); |
|
982 | - } |
|
983 | - |
|
984 | - /** |
|
985 | - * Helper function: Build translate-able strings for alert messages. |
|
986 | - * |
|
987 | - * @since 1.0.0 |
|
988 | - * |
|
989 | - * @return array of Translations and strings to be localized to JS variables |
|
990 | - */ |
|
991 | - public function translations() |
|
992 | - { |
|
993 | - $vendor_title = $this->config->get_setting('vendor/title'); |
|
994 | - |
|
995 | - /** |
|
996 | - * Filter: Allow for adding into GET parameters on support_url. |
|
997 | - * |
|
998 | - * @since 1.0.0 |
|
999 | - * |
|
1000 | - * ``` |
|
1001 | - * $url_query_args = [ |
|
1002 | - * 'message' => (string) What error should be sent to the support system. |
|
1003 | - * ]; |
|
1004 | - * ``` |
|
1005 | - * |
|
1006 | - * @param array $url_query_args { |
|
1007 | - * |
|
1008 | - * @var string $message What error should be sent to the support system. |
|
1009 | - * @var string|null $ref A sanitized reference ID, if passed. Otherwise, null. |
|
1010 | - * } |
|
1011 | - */ |
|
1012 | - $query_args = apply_filters( |
|
1013 | - 'trustedlogin/'.$this->config->ns().'/support_url/query_args', |
|
1014 | - [ |
|
1015 | - 'message' => __('Could not create TrustedLogin access.', 'gravityview'), |
|
1016 | - 'ref' => Client::get_reference_id(), |
|
1017 | - ] |
|
1018 | - ); |
|
1019 | - |
|
1020 | - $error_content = sprintf( |
|
1021 | - '<p>%s</p><p>%s</p>', |
|
1022 | - sprintf( |
|
1023 | - esc_html__('The user details could not be sent to %1$s automatically.', 'gravityview'), |
|
1024 | - $vendor_title |
|
1025 | - ), |
|
1026 | - sprintf( |
|
1027 | - __('Please <a href="%1$s" target="_blank">click here</a> to go to the %2$s support site', 'gravityview'), |
|
1028 | - esc_url(add_query_arg($query_args, $this->config->get_setting('vendor/support_url'))), |
|
1029 | - $vendor_title |
|
1030 | - ) |
|
1031 | - ); |
|
1032 | - |
|
1033 | - $translations = [ |
|
1034 | - 'buttons' => [ |
|
1035 | - 'confirm' => esc_html__('Confirm', 'gravityview'), |
|
1036 | - 'ok' => esc_html__('Ok', 'gravityview'), |
|
1037 | - 'go_to_site' => sprintf(__('Go to %1$s support site', 'gravityview'), $vendor_title), |
|
1038 | - 'close' => esc_html__('Close', 'gravityview'), |
|
1039 | - 'cancel' => esc_html__('Cancel', 'gravityview'), |
|
1040 | - 'revoke' => sprintf(esc_html__('Revoke %1$s support access', 'gravityview'), $vendor_title), |
|
1041 | - 'copy' => esc_html__('Copy', 'gravityview'), |
|
1042 | - 'copied' => esc_html__('Copied!', 'gravityview'), |
|
1043 | - ], |
|
1044 | - 'a11y' => [ |
|
1045 | - 'opens_new_window' => esc_attr__('(This link opens in a new window.)', 'gravityview'), |
|
1046 | - 'copied_text' => esc_html__('The access key has been copied to your clipboard.', 'gravityview'), |
|
1047 | - ], |
|
1048 | - 'status' => [ |
|
1049 | - 'synced' => [ |
|
1050 | - 'title' => esc_html__('Support access granted', 'gravityview'), |
|
1051 | - 'content' => sprintf( |
|
1052 | - __('A temporary support user has been created, and sent to %1$s support.', 'gravityview'), |
|
1053 | - $vendor_title |
|
1054 | - ), |
|
1055 | - ], |
|
1056 | - 'pending' => [ |
|
1057 | - 'content' => sprintf(__('Generating & encrypting secure support access for %1$s', 'gravityview'), $vendor_title), |
|
1058 | - ], |
|
1059 | - 'extending' => [ |
|
1060 | - 'content' => sprintf(__('Extending support access for %1$s by %2$s', 'gravityview'), $vendor_title, human_time_diff(time(), time() + $this->config->get_setting('decay'))), |
|
1061 | - ], |
|
1062 | - 'syncing' => [ |
|
1063 | - 'content' => sprintf(__('Sending encrypted access to %1$s.', 'gravityview'), $vendor_title), |
|
1064 | - ], |
|
1065 | - 'error' => [ |
|
1066 | - 'title' => sprintf(__('Error syncing support user to %1$s', 'gravityview'), $vendor_title), |
|
1067 | - 'content' => wp_kses($error_content, [ |
|
1068 | - 'a' => [ |
|
1069 | - 'href' => [], |
|
1070 | - 'rel' => [], |
|
1071 | - 'target' => [], |
|
1072 | - ], |
|
1073 | - 'p' => [], |
|
1074 | - ]), |
|
1075 | - ], |
|
1076 | - 'cancel' => [ |
|
1077 | - 'title' => esc_html__('Action Cancelled', 'gravityview'), |
|
1078 | - 'content' => sprintf( |
|
1079 | - __('A support account for %1$s was not created.', 'gravityview'), |
|
1080 | - $vendor_title |
|
1081 | - ), |
|
1082 | - ], |
|
1083 | - 'failed' => [ |
|
1084 | - 'title' => esc_html__('Support Access Was Not Granted', 'gravityview'), |
|
1085 | - 'content' => esc_html__('There was an error granting access: ', 'gravityview'), |
|
1086 | - ], |
|
1087 | - 'failed_permissions' => [ |
|
1088 | - 'content' => esc_html__('Your authorized session has expired. Please refresh the page.', 'gravityview'), |
|
1089 | - ], |
|
1090 | - 'accesskey' => [ |
|
1091 | - 'title' => esc_html__('TrustedLogin Key Created', 'gravityview'), |
|
1092 | - 'content' => sprintf( |
|
1093 | - __('Share this TrustedLogin Key with %1$s to give them secure access:', 'gravityview'), |
|
1094 | - $vendor_title |
|
1095 | - ), |
|
1096 | - 'revoke_link' => esc_url(add_query_arg([Endpoint::REVOKE_SUPPORT_QUERY_PARAM => $this->config->ns()], admin_url())), |
|
1097 | - ], |
|
1098 | - 'error404' => [ |
|
1099 | - 'title' => esc_html__('The TrustedLogin vendor could not be found.', 'gravityview'), |
|
1100 | - 'content' => '', |
|
1101 | - ], |
|
1102 | - 'error409' => [ |
|
1103 | - 'title' => sprintf( |
|
1104 | - __('%1$s Support user already exists', 'gravityview'), |
|
1105 | - $vendor_title |
|
1106 | - ), |
|
1107 | - 'content' => sprintf( |
|
1108 | - wp_kses( |
|
1109 | - __('A support user for %1$s already exists. You may revoke this support access from your <a href="%2$s" target="_blank">Users list</a>.', 'gravityview'), |
|
1110 | - ['a' => ['href' => [], 'target' => []]] |
|
1111 | - ), |
|
1112 | - $vendor_title, |
|
1113 | - esc_url(admin_url('users.php?role='.$this->support_user->role->get_name())) |
|
1114 | - ), |
|
1115 | - ], |
|
1116 | - ], |
|
1117 | - ]; |
|
1118 | - |
|
1119 | - return $translations; |
|
1120 | - } |
|
1121 | - |
|
1122 | - /** |
|
1123 | - * Outputs table of created support users. |
|
1124 | - * |
|
1125 | - * @since 1.0.0 |
|
1126 | - * |
|
1127 | - * @param bool $print Whether to print and return (true) or return (false) the results. Default: true |
|
1128 | - * @param array $atts Settings for the table. { |
|
1129 | - * |
|
1130 | - * @var bool $current_url Whether to generate Revoke links based on the current URL. Default: false. |
|
1131 | - * } |
|
1132 | - * |
|
1133 | - * @return string HTML table of active support users for vendor. Empty string if current user can't `create_users` |
|
1134 | - */ |
|
1135 | - public function output_support_users($print = true, $atts = []) |
|
1136 | - { |
|
1137 | - if ((!is_admin() && !$this->is_login_screen()) || !current_user_can('create_users')) { |
|
1138 | - return ''; |
|
1139 | - } |
|
1140 | - |
|
1141 | - // The `trustedlogin/{$ns}/button` action passes an empty string |
|
1142 | - if ('' === $print) { |
|
1143 | - $print = true; |
|
1144 | - } |
|
1145 | - |
|
1146 | - $support_users = $this->support_user->get_all(); |
|
1147 | - |
|
1148 | - if (empty($support_users)) { |
|
1149 | - $return = '<h3>'.sprintf(esc_html__('No %s users exist.', 'gravityview'), $this->config->get_setting('vendor/title')).'</h3>'; |
|
1150 | - |
|
1151 | - if ($print) { |
|
1152 | - echo $return; |
|
1153 | - } |
|
1154 | - |
|
1155 | - return $return; |
|
1156 | - } |
|
1157 | - |
|
1158 | - $default_atts = [ |
|
1159 | - 'current_url' => false, |
|
1160 | - ]; |
|
1161 | - |
|
1162 | - $atts = wp_parse_args($atts, $default_atts); |
|
1163 | - |
|
1164 | - $return = ''; |
|
1165 | - |
|
1166 | - $access_key_template = <<<'EOD' |
|
648 | + $content = [ |
|
649 | + 'local_site' => sprintf(esc_html__('%s support may not be able to access this site.', 'gravityview'), $this->config->get_setting('vendor/title')), |
|
650 | + 'need_access' => esc_html__('This website is running in a local development environment. To provide support, we must be able to access your site using a publicly-accessible URL.', 'gravityview'), |
|
651 | + 'about_live_access_url' => esc_url($this->config->get_setting('vendor/about_live_access_url', self::ABOUT_LIVE_ACCESS_URL)), |
|
652 | + 'learn_more' => esc_html__('Learn more.', 'gravityview'), |
|
653 | + ]; |
|
654 | + |
|
655 | + return $this->prepare_output($notice_template, $content); |
|
656 | + } |
|
657 | + |
|
658 | + /** |
|
659 | + * @return string |
|
660 | + */ |
|
661 | + private function get_logo_html() |
|
662 | + { |
|
663 | + $logo_url = $this->config->get_setting('vendor/logo_url'); |
|
664 | + |
|
665 | + $logo_output = ''; |
|
666 | + |
|
667 | + if (!empty($logo_url)) { |
|
668 | + $logo_output = sprintf( |
|
669 | + '<a href="%1$s" title="%2$s" target="_blank" rel="noreferrer noopener"><img src="%3$s" alt="%4$s" /></a>', |
|
670 | + esc_url($this->config->get_setting('vendor/website')), |
|
671 | + // translators: %s is replaced with the name of the software developer (e.g. "Acme Widgets") |
|
672 | + sprintf('Visit the %s website (opens in a new tab)', $this->config->get_setting('vendor/title')), |
|
673 | + esc_attr($this->config->get_setting('vendor/logo_url')), |
|
674 | + esc_attr($this->config->get_setting('vendor/title')) |
|
675 | + ); |
|
676 | + } |
|
677 | + |
|
678 | + return $logo_output; |
|
679 | + } |
|
680 | + |
|
681 | + /** |
|
682 | + * Returns the HTML for the footer in the Auth form. |
|
683 | + * |
|
684 | + * @return string |
|
685 | + */ |
|
686 | + private function get_footer_html() |
|
687 | + { |
|
688 | + $support_url = $this->config->get_setting('vendor/support_url'); |
|
689 | + |
|
690 | + if ($reference_id = Client::get_reference_id()) { |
|
691 | + $support_args = [ |
|
692 | + 'tl' => Client::VERSION, |
|
693 | + 'ref' => $reference_id, |
|
694 | + 'ns' => $this->config->ns(), |
|
695 | + ]; |
|
696 | + |
|
697 | + $support_url = add_query_arg($support_args, $support_url); |
|
698 | + } |
|
699 | + |
|
700 | + $footer_links = [ |
|
701 | + esc_html__('Learn about TrustedLogin', 'gravityview') => self::ABOUT_TL_URL, |
|
702 | + sprintf('Visit %s support', $this->config->get_setting('vendor/title')) => $support_url, |
|
703 | + ]; |
|
704 | + |
|
705 | + /** |
|
706 | + * Filter trustedlogin/template/auth/footer_links. |
|
707 | + * |
|
708 | + * Used to add/remove Footer Links on grantlink page |
|
709 | + * |
|
710 | + * @since 1.0.0 |
|
711 | + * |
|
712 | + * @param array Array of links to show in auth footer (Key is anchor text; Value is URL) |
|
713 | + **/ |
|
714 | + $footer_links = apply_filters('trustedlogin/'.$this->config->ns().'/template/auth/footer_links', $footer_links); |
|
715 | + |
|
716 | + $footer_links_output = ''; |
|
717 | + foreach ($footer_links as $text => $link) { |
|
718 | + $footer_links_output .= sprintf( |
|
719 | + '<li><a href="%1$s" target="_blank">%2$s</a></li>', |
|
720 | + esc_url($link), |
|
721 | + esc_html($text) |
|
722 | + ); |
|
723 | + } |
|
724 | + |
|
725 | + $footer_output = ''; |
|
726 | + if (!empty($footer_links_output)) { |
|
727 | + $footer_output = sprintf('<ul>%1$s</ul>', $footer_links_output); |
|
728 | + } |
|
729 | + |
|
730 | + return $footer_output; |
|
731 | + } |
|
732 | + |
|
733 | + private function prepare_output($template, $content, $wp_kses = true) |
|
734 | + { |
|
735 | + $output_html = $template; |
|
736 | + |
|
737 | + foreach ($content as $key => $value) { |
|
738 | + $output_html = str_replace('{{'.$key.'}}', $value, $output_html); |
|
739 | + } |
|
740 | + |
|
741 | + if ($wp_kses) { |
|
742 | + |
|
743 | + // Allow SVGs for logos |
|
744 | + $allowed_protocols = wp_allowed_protocols(); |
|
745 | + $allowed_protocols[] = 'data'; |
|
746 | + |
|
747 | + $output_html = wp_kses( |
|
748 | + $output_html, |
|
749 | + [ |
|
750 | + 'a' => [ |
|
751 | + 'class' => [], |
|
752 | + 'id' => [], |
|
753 | + 'href' => [], |
|
754 | + 'title' => [], |
|
755 | + 'rel' => [], |
|
756 | + 'target' => [], |
|
757 | + 'data-toggle' => [], |
|
758 | + 'data-access' => [], |
|
759 | + ], |
|
760 | + 'img' => [ |
|
761 | + 'class' => [], |
|
762 | + 'id' => [], |
|
763 | + 'src' => [], |
|
764 | + 'href' => [], |
|
765 | + 'alt' => [], |
|
766 | + 'title' => [], |
|
767 | + ], |
|
768 | + 'span' => [ |
|
769 | + 'class' => [], |
|
770 | + 'id' => [], |
|
771 | + 'title' => [], |
|
772 | + 'data-toggle' => [], |
|
773 | + 'style' => [], |
|
774 | + ], |
|
775 | + 'label' => ['class' => [], 'id' => [], 'for' => []], |
|
776 | + 'code' => ['class' => [], 'id' => []], |
|
777 | + 'tt' => ['class' => [], 'id' => []], |
|
778 | + 'pre' => ['class' => [], 'id' => []], |
|
779 | + 'table' => ['class' => [], 'id' => []], |
|
780 | + 'thead' => [], |
|
781 | + 'tfoot' => [], |
|
782 | + 'td' => ['class' => [], 'id' => [], 'colspan' => []], |
|
783 | + 'th' => ['class' => [], 'id' => [], 'colspan' => [], 'scope' => []], |
|
784 | + 'ul' => ['class' => [], 'id' => []], |
|
785 | + 'li' => ['class' => [], 'id' => []], |
|
786 | + 'p' => ['class' => [], 'id' => []], |
|
787 | + 'h1' => ['class' => [], 'id' => []], |
|
788 | + 'h2' => ['class' => [], 'id' => []], |
|
789 | + 'h3' => ['class' => [], 'id' => [], 'style' => []], |
|
790 | + 'h4' => ['class' => [], 'id' => []], |
|
791 | + 'h5' => ['class' => [], 'id' => []], |
|
792 | + 'div' => ['class' => [], 'id' => [], 'aria-live' => [], 'style' => []], |
|
793 | + 'small' => ['class' => [], 'id' => [], 'data-toggle' => []], |
|
794 | + 'header' => ['class' => [], 'id' => []], |
|
795 | + 'footer' => ['class' => [], 'id' => []], |
|
796 | + 'section' => ['class' => [], 'id' => []], |
|
797 | + 'br' => [], |
|
798 | + 'strong' => [], |
|
799 | + 'em' => [], |
|
800 | + 'input' => [ |
|
801 | + 'class' => [], |
|
802 | + 'id' => [], |
|
803 | + 'type' => ['text'], |
|
804 | + 'value' => [], |
|
805 | + 'size' => [], |
|
806 | + 'aria-live' => [], |
|
807 | + 'aria-label' => [], |
|
808 | + 'style' => [], |
|
809 | + ], |
|
810 | + 'button' => [ |
|
811 | + 'class' => [], |
|
812 | + 'id' => [], |
|
813 | + 'aria-live' => [], |
|
814 | + 'style' => [], |
|
815 | + 'title' => [], |
|
816 | + ], |
|
817 | + ], |
|
818 | + $allowed_protocols |
|
819 | + ); |
|
820 | + } |
|
821 | + |
|
822 | + return normalize_whitespace($output_html); |
|
823 | + } |
|
824 | + |
|
825 | + /** |
|
826 | + * Output the TrustedLogin Button and required scripts. |
|
827 | + * |
|
828 | + * @since 1.0.0 |
|
829 | + * |
|
830 | + * @param array $atts {@see get_button()} for configuration array |
|
831 | + * @param bool $print Should results be printed and returned (true) or only returned (false) |
|
832 | + * |
|
833 | + * @return string the HTML output |
|
834 | + */ |
|
835 | + public function generate_button($atts = [], $print = true) |
|
836 | + { |
|
837 | + if (!current_user_can('create_users')) { |
|
838 | + return ''; |
|
839 | + } |
|
840 | + |
|
841 | + if (!wp_script_is('trustedlogin-'.$this->config->ns(), 'registered')) { |
|
842 | + $this->logging->log('JavaScript is not registered. Make sure `trustedlogin` handle is added to "no-conflict" plugin settings.', __METHOD__, 'error'); |
|
843 | + } |
|
844 | + |
|
845 | + if (!wp_style_is('trustedlogin-'.$this->config->ns(), 'registered')) { |
|
846 | + $this->logging->log('Style is not registered. Make sure `trustedlogin` handle is added to "no-conflict" plugin settings.', __METHOD__, 'error'); |
|
847 | + } |
|
848 | + |
|
849 | + wp_enqueue_style('trustedlogin-'.$this->config->ns()); |
|
850 | + |
|
851 | + $button_settings = [ |
|
852 | + 'vendor' => $this->config->get_setting('vendor'), |
|
853 | + 'ajaxurl' => admin_url('admin-ajax.php'), |
|
854 | + '_nonce' => wp_create_nonce('tl_nonce-'.get_current_user_id()), |
|
855 | + 'lang' => $this->translations(), |
|
856 | + 'debug' => $this->logging->is_enabled(), |
|
857 | + 'selector' => '.button-trustedlogin-'.$this->config->ns(), |
|
858 | + 'reference_id' => Client::get_reference_id(), |
|
859 | + 'query_string' => esc_url(remove_query_arg([ |
|
860 | + Endpoint::REVOKE_SUPPORT_QUERY_PARAM, |
|
861 | + '_wpnonce', |
|
862 | + ])), |
|
863 | + ]; |
|
864 | + |
|
865 | + // TODO: Add data to tl_obj when detecting that it's already been localized by another vendor |
|
866 | + wp_localize_script('trustedlogin-'.$this->config->ns(), 'tl_obj', $button_settings); |
|
867 | + |
|
868 | + wp_enqueue_script('trustedlogin-'.$this->config->ns()); |
|
869 | + |
|
870 | + $return = $this->get_button($atts); |
|
871 | + |
|
872 | + if ($print) { |
|
873 | + echo $return; |
|
874 | + } |
|
875 | + |
|
876 | + return $return; |
|
877 | + } |
|
878 | + |
|
879 | + /** |
|
880 | + * Generates HTML for a TrustedLogin Grant Access button. |
|
881 | + * |
|
882 | + * @param array $atts { |
|
883 | + * |
|
884 | + * @var string $text Button text to grant access. Sanitized using esc_html(). Default: "Grant %s Access" |
|
885 | + * (%s replaced with vendor/title setting) |
|
886 | + * @var string $exists_text Button text when vendor already has a support account. Sanitized using esc_html(). |
|
887 | + * Default: "Extend %s Access" (%s replaced with vendor/title setting) |
|
888 | + * @var string $size WordPress CSS button size. Options: 'small', 'normal', 'large', 'hero'. Default: "hero" |
|
889 | + * @var string $class CSS class added to the button. Default: "button-primary" |
|
890 | + * @var string $tag Tag used to display the button. Options: 'a', 'button', 'span'. Default: "a" |
|
891 | + * @var bool $powered_by Whether to display the TrustedLogin badge on the button. Default: true |
|
892 | + * @var string $support_url The URL to use as a backup if JavaScript fails or isn't available. Sanitized using |
|
893 | + * esc_url(). Default: `vendor/support_url` configuration setting URL. |
|
894 | + * } |
|
895 | + * |
|
896 | + * @return string |
|
897 | + */ |
|
898 | + public function get_button($atts = []) |
|
899 | + { |
|
900 | + $defaults = [ |
|
901 | + 'text' => sprintf(esc_html__('Grant %s Access', 'gravityview'), $this->config->get_display_name()), |
|
902 | + 'exists_text' => sprintf(esc_html__('Extend %s Access', 'gravityview'), $this->config->get_display_name(), ucwords(human_time_diff(time(), time() + $this->config->get_setting('decay')))), |
|
903 | + 'size' => 'hero', |
|
904 | + 'class' => 'button-primary', |
|
905 | + 'tag' => 'a', // "a", "button", "span" |
|
906 | + 'powered_by' => false, |
|
907 | + 'support_url' => $this->config->get_setting('vendor/support_url'), |
|
908 | + ]; |
|
909 | + |
|
910 | + $sizes = ['small', 'normal', 'large', 'hero']; |
|
911 | + |
|
912 | + $atts = wp_parse_args($atts, $defaults); |
|
913 | + |
|
914 | + switch ($atts['size']) { |
|
915 | + case '': |
|
916 | + $css_class = ''; |
|
917 | + break; |
|
918 | + case 'normal': |
|
919 | + $css_class = 'button'; |
|
920 | + break; |
|
921 | + default: |
|
922 | + if (!in_array($atts['size'], $sizes)) { |
|
923 | + $atts['size'] = 'hero'; |
|
924 | + } |
|
925 | + |
|
926 | + $css_class = 'button button-'.$atts['size']; |
|
927 | + } |
|
928 | + |
|
929 | + $_valid_tags = ['a', 'button', 'span']; |
|
930 | + |
|
931 | + if (!empty($atts['tag']) && in_array(strtolower($atts['tag']), $_valid_tags, true)) { |
|
932 | + $tag = $atts['tag']; |
|
933 | + } else { |
|
934 | + $tag = 'a'; |
|
935 | + } |
|
936 | + |
|
937 | + $data_atts = []; |
|
938 | + |
|
939 | + if ($this->support_user->get_all()) { |
|
940 | + $text = '<span class="dashicons dashicons-update-alt"></span>'.esc_html($atts['exists_text']); |
|
941 | + $href = admin_url('users.php?role='.$this->support_user->role->get_name()); |
|
942 | + $data_atts['access'] = 'extend'; |
|
943 | + } else { |
|
944 | + $text = esc_html($atts['text']); |
|
945 | + $href = $atts['support_url']; |
|
946 | + $data_atts['access'] = 'grant'; |
|
947 | + } |
|
948 | + |
|
949 | + $css_class = implode(' ', [$css_class, $atts['class']]); |
|
950 | + $css_class = trim($css_class); |
|
951 | + |
|
952 | + $data_string = ''; |
|
953 | + foreach ($data_atts as $key => $value) { |
|
954 | + $data_string .= sprintf(' data-%s="%s"', esc_attr($key), esc_attr($value)); |
|
955 | + } |
|
956 | + |
|
957 | + $powered_by = ''; |
|
958 | + if ($atts['powered_by']) { |
|
959 | + $powered_by = sprintf( |
|
960 | + '<small><span class="trustedlogin-logo"></span>%s</small>', |
|
961 | + esc_html__('Secured by TrustedLogin', 'gravityview') |
|
962 | + ); |
|
963 | + } |
|
964 | + |
|
965 | + $anchor_html = $text.$powered_by; |
|
966 | + |
|
967 | + return sprintf( |
|
968 | + '<%1$s href="%2$s" class="%3$s button-trustedlogin-%4$s" aria-role="button" %5$s>%6$s</%1$s>', |
|
969 | + /* %1$s */ |
|
970 | + $tag, |
|
971 | + /* %2$s */ |
|
972 | + esc_url($href), |
|
973 | + /* %3$s */ |
|
974 | + esc_attr($css_class), |
|
975 | + /* %4$s */ |
|
976 | + $this->config->ns(), |
|
977 | + /* %5$s */ |
|
978 | + $data_string, |
|
979 | + /* %6$s */ |
|
980 | + $anchor_html |
|
981 | + ); |
|
982 | + } |
|
983 | + |
|
984 | + /** |
|
985 | + * Helper function: Build translate-able strings for alert messages. |
|
986 | + * |
|
987 | + * @since 1.0.0 |
|
988 | + * |
|
989 | + * @return array of Translations and strings to be localized to JS variables |
|
990 | + */ |
|
991 | + public function translations() |
|
992 | + { |
|
993 | + $vendor_title = $this->config->get_setting('vendor/title'); |
|
994 | + |
|
995 | + /** |
|
996 | + * Filter: Allow for adding into GET parameters on support_url. |
|
997 | + * |
|
998 | + * @since 1.0.0 |
|
999 | + * |
|
1000 | + * ``` |
|
1001 | + * $url_query_args = [ |
|
1002 | + * 'message' => (string) What error should be sent to the support system. |
|
1003 | + * ]; |
|
1004 | + * ``` |
|
1005 | + * |
|
1006 | + * @param array $url_query_args { |
|
1007 | + * |
|
1008 | + * @var string $message What error should be sent to the support system. |
|
1009 | + * @var string|null $ref A sanitized reference ID, if passed. Otherwise, null. |
|
1010 | + * } |
|
1011 | + */ |
|
1012 | + $query_args = apply_filters( |
|
1013 | + 'trustedlogin/'.$this->config->ns().'/support_url/query_args', |
|
1014 | + [ |
|
1015 | + 'message' => __('Could not create TrustedLogin access.', 'gravityview'), |
|
1016 | + 'ref' => Client::get_reference_id(), |
|
1017 | + ] |
|
1018 | + ); |
|
1019 | + |
|
1020 | + $error_content = sprintf( |
|
1021 | + '<p>%s</p><p>%s</p>', |
|
1022 | + sprintf( |
|
1023 | + esc_html__('The user details could not be sent to %1$s automatically.', 'gravityview'), |
|
1024 | + $vendor_title |
|
1025 | + ), |
|
1026 | + sprintf( |
|
1027 | + __('Please <a href="%1$s" target="_blank">click here</a> to go to the %2$s support site', 'gravityview'), |
|
1028 | + esc_url(add_query_arg($query_args, $this->config->get_setting('vendor/support_url'))), |
|
1029 | + $vendor_title |
|
1030 | + ) |
|
1031 | + ); |
|
1032 | + |
|
1033 | + $translations = [ |
|
1034 | + 'buttons' => [ |
|
1035 | + 'confirm' => esc_html__('Confirm', 'gravityview'), |
|
1036 | + 'ok' => esc_html__('Ok', 'gravityview'), |
|
1037 | + 'go_to_site' => sprintf(__('Go to %1$s support site', 'gravityview'), $vendor_title), |
|
1038 | + 'close' => esc_html__('Close', 'gravityview'), |
|
1039 | + 'cancel' => esc_html__('Cancel', 'gravityview'), |
|
1040 | + 'revoke' => sprintf(esc_html__('Revoke %1$s support access', 'gravityview'), $vendor_title), |
|
1041 | + 'copy' => esc_html__('Copy', 'gravityview'), |
|
1042 | + 'copied' => esc_html__('Copied!', 'gravityview'), |
|
1043 | + ], |
|
1044 | + 'a11y' => [ |
|
1045 | + 'opens_new_window' => esc_attr__('(This link opens in a new window.)', 'gravityview'), |
|
1046 | + 'copied_text' => esc_html__('The access key has been copied to your clipboard.', 'gravityview'), |
|
1047 | + ], |
|
1048 | + 'status' => [ |
|
1049 | + 'synced' => [ |
|
1050 | + 'title' => esc_html__('Support access granted', 'gravityview'), |
|
1051 | + 'content' => sprintf( |
|
1052 | + __('A temporary support user has been created, and sent to %1$s support.', 'gravityview'), |
|
1053 | + $vendor_title |
|
1054 | + ), |
|
1055 | + ], |
|
1056 | + 'pending' => [ |
|
1057 | + 'content' => sprintf(__('Generating & encrypting secure support access for %1$s', 'gravityview'), $vendor_title), |
|
1058 | + ], |
|
1059 | + 'extending' => [ |
|
1060 | + 'content' => sprintf(__('Extending support access for %1$s by %2$s', 'gravityview'), $vendor_title, human_time_diff(time(), time() + $this->config->get_setting('decay'))), |
|
1061 | + ], |
|
1062 | + 'syncing' => [ |
|
1063 | + 'content' => sprintf(__('Sending encrypted access to %1$s.', 'gravityview'), $vendor_title), |
|
1064 | + ], |
|
1065 | + 'error' => [ |
|
1066 | + 'title' => sprintf(__('Error syncing support user to %1$s', 'gravityview'), $vendor_title), |
|
1067 | + 'content' => wp_kses($error_content, [ |
|
1068 | + 'a' => [ |
|
1069 | + 'href' => [], |
|
1070 | + 'rel' => [], |
|
1071 | + 'target' => [], |
|
1072 | + ], |
|
1073 | + 'p' => [], |
|
1074 | + ]), |
|
1075 | + ], |
|
1076 | + 'cancel' => [ |
|
1077 | + 'title' => esc_html__('Action Cancelled', 'gravityview'), |
|
1078 | + 'content' => sprintf( |
|
1079 | + __('A support account for %1$s was not created.', 'gravityview'), |
|
1080 | + $vendor_title |
|
1081 | + ), |
|
1082 | + ], |
|
1083 | + 'failed' => [ |
|
1084 | + 'title' => esc_html__('Support Access Was Not Granted', 'gravityview'), |
|
1085 | + 'content' => esc_html__('There was an error granting access: ', 'gravityview'), |
|
1086 | + ], |
|
1087 | + 'failed_permissions' => [ |
|
1088 | + 'content' => esc_html__('Your authorized session has expired. Please refresh the page.', 'gravityview'), |
|
1089 | + ], |
|
1090 | + 'accesskey' => [ |
|
1091 | + 'title' => esc_html__('TrustedLogin Key Created', 'gravityview'), |
|
1092 | + 'content' => sprintf( |
|
1093 | + __('Share this TrustedLogin Key with %1$s to give them secure access:', 'gravityview'), |
|
1094 | + $vendor_title |
|
1095 | + ), |
|
1096 | + 'revoke_link' => esc_url(add_query_arg([Endpoint::REVOKE_SUPPORT_QUERY_PARAM => $this->config->ns()], admin_url())), |
|
1097 | + ], |
|
1098 | + 'error404' => [ |
|
1099 | + 'title' => esc_html__('The TrustedLogin vendor could not be found.', 'gravityview'), |
|
1100 | + 'content' => '', |
|
1101 | + ], |
|
1102 | + 'error409' => [ |
|
1103 | + 'title' => sprintf( |
|
1104 | + __('%1$s Support user already exists', 'gravityview'), |
|
1105 | + $vendor_title |
|
1106 | + ), |
|
1107 | + 'content' => sprintf( |
|
1108 | + wp_kses( |
|
1109 | + __('A support user for %1$s already exists. You may revoke this support access from your <a href="%2$s" target="_blank">Users list</a>.', 'gravityview'), |
|
1110 | + ['a' => ['href' => [], 'target' => []]] |
|
1111 | + ), |
|
1112 | + $vendor_title, |
|
1113 | + esc_url(admin_url('users.php?role='.$this->support_user->role->get_name())) |
|
1114 | + ), |
|
1115 | + ], |
|
1116 | + ], |
|
1117 | + ]; |
|
1118 | + |
|
1119 | + return $translations; |
|
1120 | + } |
|
1121 | + |
|
1122 | + /** |
|
1123 | + * Outputs table of created support users. |
|
1124 | + * |
|
1125 | + * @since 1.0.0 |
|
1126 | + * |
|
1127 | + * @param bool $print Whether to print and return (true) or return (false) the results. Default: true |
|
1128 | + * @param array $atts Settings for the table. { |
|
1129 | + * |
|
1130 | + * @var bool $current_url Whether to generate Revoke links based on the current URL. Default: false. |
|
1131 | + * } |
|
1132 | + * |
|
1133 | + * @return string HTML table of active support users for vendor. Empty string if current user can't `create_users` |
|
1134 | + */ |
|
1135 | + public function output_support_users($print = true, $atts = []) |
|
1136 | + { |
|
1137 | + if ((!is_admin() && !$this->is_login_screen()) || !current_user_can('create_users')) { |
|
1138 | + return ''; |
|
1139 | + } |
|
1140 | + |
|
1141 | + // The `trustedlogin/{$ns}/button` action passes an empty string |
|
1142 | + if ('' === $print) { |
|
1143 | + $print = true; |
|
1144 | + } |
|
1145 | + |
|
1146 | + $support_users = $this->support_user->get_all(); |
|
1147 | + |
|
1148 | + if (empty($support_users)) { |
|
1149 | + $return = '<h3>'.sprintf(esc_html__('No %s users exist.', 'gravityview'), $this->config->get_setting('vendor/title')).'</h3>'; |
|
1150 | + |
|
1151 | + if ($print) { |
|
1152 | + echo $return; |
|
1153 | + } |
|
1154 | + |
|
1155 | + return $return; |
|
1156 | + } |
|
1157 | + |
|
1158 | + $default_atts = [ |
|
1159 | + 'current_url' => false, |
|
1160 | + ]; |
|
1161 | + |
|
1162 | + $atts = wp_parse_args($atts, $default_atts); |
|
1163 | + |
|
1164 | + $return = ''; |
|
1165 | + |
|
1166 | + $access_key_template = <<<'EOD' |
|
1167 | 1167 | <%6$s class="tl-%1$s-auth__accesskey"> |
1168 | 1168 | <label for="tl-%1$s-access-key"><h3>%2$s</h3></label> |
1169 | 1169 | <p>%8$s</p> |
@@ -1175,57 +1175,57 @@ discard block |
||
1175 | 1175 | </%6$s> |
1176 | 1176 | EOD; |
1177 | 1177 | |
1178 | - $access_key_output = sprintf( |
|
1179 | - $access_key_template, |
|
1180 | - /* %1$s */ |
|
1181 | - sanitize_title($this->config->ns()), |
|
1182 | - /* %2$s */ |
|
1183 | - esc_html__('Site access key:', 'gravityview'), |
|
1184 | - /* %3$s */ |
|
1185 | - esc_html__('Access Key', 'gravityview'), |
|
1186 | - /* %4$s */ |
|
1187 | - esc_attr($this->site_access->get_access_key()), |
|
1188 | - /* %5$s */ |
|
1189 | - esc_html__('Copy', 'gravityview'), |
|
1190 | - /* %6$s */ |
|
1191 | - 'div', |
|
1192 | - /* %7$s */ |
|
1193 | - esc_html__('Copy the access key to your clipboard', 'gravityview'), |
|
1194 | - sprintf('The access key is not a password; only %1$s will be able to access your site using this code. You may share this access key on support forums.', $this->support_user->get_first()->display_name) |
|
1195 | - ); |
|
1196 | - |
|
1197 | - $return .= $access_key_output; |
|
1198 | - |
|
1199 | - if ($print) { |
|
1200 | - echo $return; |
|
1201 | - } |
|
1202 | - |
|
1203 | - return $return; |
|
1204 | - } |
|
1205 | - |
|
1206 | - /** |
|
1207 | - * Add admin_notices hooks. |
|
1208 | - * |
|
1209 | - * @return void |
|
1210 | - */ |
|
1211 | - public function admin_notices() |
|
1212 | - { |
|
1213 | - add_action('admin_notices', [$this, 'admin_notice_revoked']); |
|
1214 | - } |
|
1215 | - |
|
1216 | - /** |
|
1217 | - * Notice: Shown when a support user is manually revoked by admin;. |
|
1218 | - * |
|
1219 | - * @return void |
|
1220 | - */ |
|
1221 | - public function admin_notice_revoked() |
|
1222 | - { |
|
1223 | - static $displayed_notice; |
|
1224 | - |
|
1225 | - // Only show notice once |
|
1226 | - if ($displayed_notice) { |
|
1227 | - return; |
|
1228 | - } ?> |
|
1178 | + $access_key_output = sprintf( |
|
1179 | + $access_key_template, |
|
1180 | + /* %1$s */ |
|
1181 | + sanitize_title($this->config->ns()), |
|
1182 | + /* %2$s */ |
|
1183 | + esc_html__('Site access key:', 'gravityview'), |
|
1184 | + /* %3$s */ |
|
1185 | + esc_html__('Access Key', 'gravityview'), |
|
1186 | + /* %4$s */ |
|
1187 | + esc_attr($this->site_access->get_access_key()), |
|
1188 | + /* %5$s */ |
|
1189 | + esc_html__('Copy', 'gravityview'), |
|
1190 | + /* %6$s */ |
|
1191 | + 'div', |
|
1192 | + /* %7$s */ |
|
1193 | + esc_html__('Copy the access key to your clipboard', 'gravityview'), |
|
1194 | + sprintf('The access key is not a password; only %1$s will be able to access your site using this code. You may share this access key on support forums.', $this->support_user->get_first()->display_name) |
|
1195 | + ); |
|
1196 | + |
|
1197 | + $return .= $access_key_output; |
|
1198 | + |
|
1199 | + if ($print) { |
|
1200 | + echo $return; |
|
1201 | + } |
|
1202 | + |
|
1203 | + return $return; |
|
1204 | + } |
|
1205 | + |
|
1206 | + /** |
|
1207 | + * Add admin_notices hooks. |
|
1208 | + * |
|
1209 | + * @return void |
|
1210 | + */ |
|
1211 | + public function admin_notices() |
|
1212 | + { |
|
1213 | + add_action('admin_notices', [$this, 'admin_notice_revoked']); |
|
1214 | + } |
|
1215 | + |
|
1216 | + /** |
|
1217 | + * Notice: Shown when a support user is manually revoked by admin;. |
|
1218 | + * |
|
1219 | + * @return void |
|
1220 | + */ |
|
1221 | + public function admin_notice_revoked() |
|
1222 | + { |
|
1223 | + static $displayed_notice; |
|
1224 | + |
|
1225 | + // Only show notice once |
|
1226 | + if ($displayed_notice) { |
|
1227 | + return; |
|
1228 | + } ?> |
|
1229 | 1229 | <div class="notice notice-success is-dismissible"> |
1230 | 1230 | <h3><?php echo esc_html(sprintf(__('%s access revoked.', 'gravityview'), $this->config->get_setting('vendor/title'))); ?></h3> |
1231 | 1231 | <?php if (!current_user_can('delete_users')) { ?> |
@@ -1234,6 +1234,6 @@ discard block |
||
1234 | 1234 | </div> |
1235 | 1235 | <?php |
1236 | 1236 | |
1237 | - $displayed_notice = true; |
|
1238 | - } |
|
1237 | + $displayed_notice = true; |
|
1238 | + } |
|
1239 | 1239 | } |
@@ -16,7 +16,7 @@ discard block |
||
16 | 16 | namespace GravityView\TrustedLogin; |
17 | 17 | |
18 | 18 | // Exit if accessed directly |
19 | -if (!defined('ABSPATH')) { |
|
19 | +if ( ! defined( 'ABSPATH' ) ) { |
|
20 | 20 | exit; |
21 | 21 | } |
22 | 22 | |
@@ -57,37 +57,37 @@ discard block |
||
57 | 57 | * |
58 | 58 | * @param Config $config |
59 | 59 | */ |
60 | - public function __construct(Config $config, Logging $logging) |
|
60 | + public function __construct( Config $config, Logging $logging ) |
|
61 | 61 | { |
62 | 62 | $this->config = $config; |
63 | 63 | $this->logging = $logging; |
64 | - $this->site_access = new SiteAccess($config, $logging); |
|
65 | - $this->support_user = new SupportUser($config, $logging); |
|
64 | + $this->site_access = new SiteAccess( $config, $logging ); |
|
65 | + $this->support_user = new SupportUser( $config, $logging ); |
|
66 | 66 | } |
67 | 67 | |
68 | 68 | public function init() |
69 | 69 | { |
70 | - add_action('trustedlogin/'.$this->config->ns().'/button', [$this, 'generate_button'], 10, 2); |
|
71 | - add_action('trustedlogin/'.$this->config->ns().'/users_table', [ |
|
70 | + add_action( 'trustedlogin/' . $this->config->ns() . '/button', [ $this, 'generate_button' ], 10, 2 ); |
|
71 | + add_action( 'trustedlogin/' . $this->config->ns() . '/users_table', [ |
|
72 | 72 | $this, |
73 | 73 | 'output_support_users', |
74 | - ], 20); |
|
75 | - add_action('trustedlogin/'.$this->config->ns().'/auth_screen', [$this, 'print_auth_screen'], 20); |
|
76 | - add_action('login_form_trustedlogin', [$this, 'maybe_print_request_screen'], 20); |
|
77 | - add_filter('user_row_actions', [$this, 'user_row_action_revoke'], 10, 2); |
|
78 | - add_action('admin_bar_menu', [$this, 'admin_bar_add_toolbar_items'], 100); |
|
79 | - |
|
80 | - if ($this->config->get_setting('menu')) { |
|
81 | - $menu_priority = $this->config->get_setting('menu/priority', 100); |
|
82 | - add_action('admin_menu', [$this, 'admin_menu_auth_link_page'], $menu_priority); |
|
74 | + ], 20 ); |
|
75 | + add_action( 'trustedlogin/' . $this->config->ns() . '/auth_screen', [ $this, 'print_auth_screen' ], 20 ); |
|
76 | + add_action( 'login_form_trustedlogin', [ $this, 'maybe_print_request_screen' ], 20 ); |
|
77 | + add_filter( 'user_row_actions', [ $this, 'user_row_action_revoke' ], 10, 2 ); |
|
78 | + add_action( 'admin_bar_menu', [ $this, 'admin_bar_add_toolbar_items' ], 100 ); |
|
79 | + |
|
80 | + if ( $this->config->get_setting( 'menu' ) ) { |
|
81 | + $menu_priority = $this->config->get_setting( 'menu/priority', 100 ); |
|
82 | + add_action( 'admin_menu', [ $this, 'admin_menu_auth_link_page' ], $menu_priority ); |
|
83 | 83 | } |
84 | 84 | |
85 | - if ($this->config->get_setting('register_assets', true)) { |
|
86 | - add_action('admin_enqueue_scripts', [$this, 'register_assets']); |
|
87 | - add_action('login_enqueue_scripts', [$this, 'register_assets']); |
|
85 | + if ( $this->config->get_setting( 'register_assets', true ) ) { |
|
86 | + add_action( 'admin_enqueue_scripts', [ $this, 'register_assets' ] ); |
|
87 | + add_action( 'login_enqueue_scripts', [ $this, 'register_assets' ] ); |
|
88 | 88 | } |
89 | 89 | |
90 | - add_action('trustedlogin/'.$this->config->ns().'/admin/access_revoked', [$this, 'admin_notices']); |
|
90 | + add_action( 'trustedlogin/' . $this->config->ns() . '/admin/access_revoked', [ $this, 'admin_notices' ] ); |
|
91 | 91 | } |
92 | 92 | |
93 | 93 | /** |
@@ -100,20 +100,20 @@ discard block |
||
100 | 100 | * |
101 | 101 | * @return array |
102 | 102 | */ |
103 | - public function user_row_action_revoke($actions, $user_object) |
|
103 | + public function user_row_action_revoke( $actions, $user_object ) |
|
104 | 104 | { |
105 | - if (!current_user_can($this->support_user->role->get_name()) && !current_user_can('delete_users')) { |
|
105 | + if ( ! current_user_can( $this->support_user->role->get_name() ) && ! current_user_can( 'delete_users' ) ) { |
|
106 | 106 | return $actions; |
107 | 107 | } |
108 | 108 | |
109 | - $revoke_url = $this->support_user->get_revoke_url($user_object); |
|
109 | + $revoke_url = $this->support_user->get_revoke_url( $user_object ); |
|
110 | 110 | |
111 | - if (!$revoke_url) { |
|
111 | + if ( ! $revoke_url ) { |
|
112 | 112 | return $actions; |
113 | 113 | } |
114 | 114 | |
115 | 115 | return [ |
116 | - 'revoke' => "<a class='trustedlogin tl-revoke submitdelete' href='".esc_url($revoke_url)."'>".esc_html__('Revoke Access', 'gravityview').'</a>', |
|
116 | + 'revoke' => "<a class='trustedlogin tl-revoke submitdelete' href='" . esc_url( $revoke_url ) . "'>" . esc_html__( 'Revoke Access', 'gravityview' ) . '</a>', |
|
117 | 117 | ]; |
118 | 118 | } |
119 | 119 | |
@@ -124,28 +124,28 @@ discard block |
||
124 | 124 | */ |
125 | 125 | public function register_assets() |
126 | 126 | { |
127 | - $registered = []; |
|
127 | + $registered = [ ]; |
|
128 | 128 | |
129 | - $registered['trustedlogin-js'] = wp_register_script( |
|
130 | - 'trustedlogin-'.$this->config->ns(), |
|
131 | - $this->config->get_setting('paths/js'), |
|
132 | - ['jquery', 'wp-a11y'], |
|
129 | + $registered[ 'trustedlogin-js' ] = wp_register_script( |
|
130 | + 'trustedlogin-' . $this->config->ns(), |
|
131 | + $this->config->get_setting( 'paths/js' ), |
|
132 | + [ 'jquery', 'wp-a11y' ], |
|
133 | 133 | Client::VERSION, |
134 | 134 | true |
135 | 135 | ); |
136 | 136 | |
137 | - $registered['trustedlogin-css'] = wp_register_style( |
|
138 | - 'trustedlogin-'.$this->config->ns(), |
|
139 | - $this->config->get_setting('paths/css'), |
|
140 | - [], |
|
137 | + $registered[ 'trustedlogin-css' ] = wp_register_style( |
|
138 | + 'trustedlogin-' . $this->config->ns(), |
|
139 | + $this->config->get_setting( 'paths/css' ), |
|
140 | + [ ], |
|
141 | 141 | Client::VERSION, |
142 | 142 | 'all' |
143 | 143 | ); |
144 | 144 | |
145 | - $registered_filtered = array_filter($registered); |
|
145 | + $registered_filtered = array_filter( $registered ); |
|
146 | 146 | |
147 | - if (count($registered) !== count($registered_filtered)) { |
|
148 | - $this->logging->log('Not all scripts and styles were registered: '.print_r($registered_filtered, true), __METHOD__, 'error'); |
|
147 | + if ( count( $registered ) !== count( $registered_filtered ) ) { |
|
148 | + $this->logging->log( 'Not all scripts and styles were registered: ' . print_r( $registered_filtered, true ), __METHOD__, 'error' ); |
|
149 | 149 | } |
150 | 150 | } |
151 | 151 | |
@@ -156,19 +156,19 @@ discard block |
||
156 | 156 | * |
157 | 157 | * @return void |
158 | 158 | */ |
159 | - public function admin_bar_add_toolbar_items($admin_bar) |
|
159 | + public function admin_bar_add_toolbar_items( $admin_bar ) |
|
160 | 160 | { |
161 | - if (!current_user_can($this->support_user->role->get_name())) { |
|
161 | + if ( ! current_user_can( $this->support_user->role->get_name() ) ) { |
|
162 | 162 | return; |
163 | 163 | } |
164 | 164 | |
165 | - if (!$admin_bar instanceof WP_Admin_Bar) { |
|
165 | + if ( ! $admin_bar instanceof WP_Admin_Bar ) { |
|
166 | 166 | return; |
167 | 167 | } |
168 | 168 | |
169 | 169 | $is_user_active = $this->support_user->is_active(); |
170 | 170 | |
171 | - if (!$is_user_active) { |
|
171 | + if ( ! $is_user_active ) { |
|
172 | 172 | return; |
173 | 173 | } |
174 | 174 | |
@@ -182,14 +182,14 @@ discard block |
||
182 | 182 | background-size: 22px 23px; |
183 | 183 | "></span>'; |
184 | 184 | |
185 | - $admin_bar->add_menu([ |
|
186 | - 'id' => 'tl-'.$this->config->ns().'-revoke', |
|
187 | - 'title' => $icon.esc_html__('Revoke TrustedLogin', 'gravityview'), |
|
188 | - 'href' => $this->support_user->get_revoke_url('all'), |
|
185 | + $admin_bar->add_menu( [ |
|
186 | + 'id' => 'tl-' . $this->config->ns() . '-revoke', |
|
187 | + 'title' => $icon . esc_html__( 'Revoke TrustedLogin', 'gravityview' ), |
|
188 | + 'href' => $this->support_user->get_revoke_url( 'all' ), |
|
189 | 189 | 'meta' => [ |
190 | 190 | 'class' => 'tl-destroy-session', |
191 | 191 | ], |
192 | - ]); |
|
192 | + ] ); |
|
193 | 193 | } |
194 | 194 | |
195 | 195 | /** |
@@ -203,29 +203,29 @@ discard block |
||
203 | 203 | */ |
204 | 204 | public function admin_menu_auth_link_page() |
205 | 205 | { |
206 | - $parent_slug = $this->config->get_setting('menu/slug', null); |
|
206 | + $parent_slug = $this->config->get_setting( 'menu/slug', null ); |
|
207 | 207 | |
208 | 208 | // When false, there will be no menus added. |
209 | - if (false === $parent_slug) { |
|
209 | + if ( false === $parent_slug ) { |
|
210 | 210 | return; |
211 | 211 | } |
212 | 212 | |
213 | 213 | $ns = $this->config->ns(); |
214 | 214 | |
215 | - $menu_slug = apply_filters('trustedlogin/'.$this->config->ns().'/admin/menu/menu_slug', 'grant-'.$ns.'-access'); |
|
215 | + $menu_slug = apply_filters( 'trustedlogin/' . $this->config->ns() . '/admin/menu/menu_slug', 'grant-' . $ns . '-access' ); |
|
216 | 216 | |
217 | - $menu_title = $this->config->get_setting('menu/title', esc_html__('Grant Support Access', 'gravityview')); |
|
217 | + $menu_title = $this->config->get_setting( 'menu/title', esc_html__( 'Grant Support Access', 'gravityview' ) ); |
|
218 | 218 | |
219 | 219 | // If empty (null or empty string), add top-level menu |
220 | - if (empty($parent_slug)) { |
|
220 | + if ( empty( $parent_slug ) ) { |
|
221 | 221 | add_menu_page( |
222 | 222 | $menu_title, |
223 | 223 | $menu_title, |
224 | 224 | 'create_users', |
225 | 225 | $menu_slug, |
226 | - [$this, 'print_auth_screen'], |
|
227 | - $this->config->get_setting('menu/icon_url', ''), |
|
228 | - $this->config->get_setting('menu/position', null) |
|
226 | + [ $this, 'print_auth_screen' ], |
|
227 | + $this->config->get_setting( 'menu/icon_url', '' ), |
|
228 | + $this->config->get_setting( 'menu/position', null ) |
|
229 | 229 | ); |
230 | 230 | |
231 | 231 | return; |
@@ -237,8 +237,8 @@ discard block |
||
237 | 237 | $menu_title, |
238 | 238 | 'create_users', |
239 | 239 | $menu_slug, |
240 | - [$this, 'print_auth_screen'], |
|
241 | - $this->config->get_setting('menu/position', null) |
|
240 | + [ $this, 'print_auth_screen' ], |
|
241 | + $this->config->get_setting( 'menu/position', null ) |
|
242 | 242 | ); |
243 | 243 | } |
244 | 244 | |
@@ -249,7 +249,7 @@ discard block |
||
249 | 249 | */ |
250 | 250 | private function is_login_screen() |
251 | 251 | { |
252 | - return did_action('login_init') && isset($_GET['ns']) && $_GET['ns'] === $this->config->ns(); |
|
252 | + return did_action( 'login_init' ) && isset( $_GET[ 'ns' ] ) && $_GET[ 'ns' ] === $this->config->ns(); |
|
253 | 253 | } |
254 | 254 | |
255 | 255 | /** |
@@ -259,18 +259,18 @@ discard block |
||
259 | 259 | */ |
260 | 260 | public function maybe_print_request_screen() |
261 | 261 | { |
262 | - if (!$this->is_login_screen()) { |
|
262 | + if ( ! $this->is_login_screen() ) { |
|
263 | 263 | return; |
264 | 264 | } |
265 | 265 | |
266 | 266 | // Once logged-in, take user back to auth request screen. |
267 | - if (!is_user_logged_in()) { |
|
268 | - $_REQUEST['redirect_to'] = site_url(add_query_arg([])); |
|
267 | + if ( ! is_user_logged_in() ) { |
|
268 | + $_REQUEST[ 'redirect_to' ] = site_url( add_query_arg( [ ] ) ); |
|
269 | 269 | |
270 | 270 | return; |
271 | 271 | } |
272 | 272 | |
273 | - if (!current_user_can('create_users')) { |
|
273 | + if ( ! current_user_can( 'create_users' ) ) { |
|
274 | 274 | return; |
275 | 275 | } |
276 | 276 | |
@@ -285,21 +285,21 @@ discard block |
||
285 | 285 | $interim_login = true; |
286 | 286 | |
287 | 287 | // The login_headertitle filter was deprecated in WP 5.2.0 for login_headertext |
288 | - if (version_compare($wp_version, '5.2.0', '<')) { |
|
289 | - add_filter('login_headertitle', '__return_empty_string'); |
|
288 | + if ( version_compare( $wp_version, '5.2.0', '<' ) ) { |
|
289 | + add_filter( 'login_headertitle', '__return_empty_string' ); |
|
290 | 290 | } else { |
291 | - add_filter('login_headertext', '__return_empty_string'); |
|
291 | + add_filter( 'login_headertext', '__return_empty_string' ); |
|
292 | 292 | } |
293 | 293 | |
294 | - add_filter('login_headerurl', function () { |
|
295 | - return $this->config->get_setting('vendor/website'); |
|
294 | + add_filter( 'login_headerurl', function() { |
|
295 | + return $this->config->get_setting( 'vendor/website' ); |
|
296 | 296 | }); |
297 | 297 | |
298 | 298 | login_header(); |
299 | 299 | |
300 | - wp_enqueue_style('common'); |
|
300 | + wp_enqueue_style( 'common' ); |
|
301 | 301 | |
302 | - wp_add_inline_style('common', $this->get_login_inline_css()); |
|
302 | + wp_add_inline_style( 'common', $this->get_login_inline_css() ); |
|
303 | 303 | |
304 | 304 | echo $this->get_auth_screen(); |
305 | 305 | |
@@ -328,7 +328,7 @@ discard block |
||
328 | 328 | margin-top: 36px; |
329 | 329 | } |
330 | 330 | .login h1 a { |
331 | - background-image: url("'.$this->config->get_setting('vendor/logo_url').'")!important; |
|
331 | + background-image: url("'.$this->config->get_setting( 'vendor/logo_url' ) . '")!important; |
|
332 | 332 | background-size: contain!important; |
333 | 333 | } |
334 | 334 | '; |
@@ -350,20 +350,20 @@ discard block |
||
350 | 350 | { |
351 | 351 | $support_users = $this->support_user->get_all(); |
352 | 352 | |
353 | - if (empty($support_users)) { |
|
353 | + if ( empty( $support_users ) ) { |
|
354 | 354 | return ''; |
355 | 355 | } |
356 | 356 | |
357 | - $support_user = $support_users[0]; |
|
357 | + $support_user = $support_users[ 0 ]; |
|
358 | 358 | |
359 | - $_user_creator_id = get_user_option($this->support_user->created_by_meta_key, $support_user->ID); |
|
360 | - $_user_creator = $_user_creator_id ? get_user_by('id', $_user_creator_id) : false; |
|
359 | + $_user_creator_id = get_user_option( $this->support_user->created_by_meta_key, $support_user->ID ); |
|
360 | + $_user_creator = $_user_creator_id ? get_user_by( 'id', $_user_creator_id ) : false; |
|
361 | 361 | |
362 | - $unknown_user_text = sprintf(esc_html__('Unknown (User #%d)', 'gravityview'), $_user_creator_id); |
|
362 | + $unknown_user_text = sprintf( esc_html__( 'Unknown (User #%d)', 'gravityview' ), $_user_creator_id ); |
|
363 | 363 | |
364 | - $auth_meta = ($_user_creator && $_user_creator->exists()) ? esc_html($_user_creator->display_name) : $unknown_user_text; |
|
364 | + $auth_meta = ( $_user_creator && $_user_creator->exists() ) ? esc_html( $_user_creator->display_name ) : $unknown_user_text; |
|
365 | 365 | |
366 | - $revoke_url = $this->support_user->get_revoke_url($support_user); |
|
366 | + $revoke_url = $this->support_user->get_revoke_url( $support_user ); |
|
367 | 367 | |
368 | 368 | $template = ' |
369 | 369 | {{revoke_access_button}} |
@@ -372,11 +372,11 @@ discard block |
||
372 | 372 | |
373 | 373 | $content = [ |
374 | 374 | 'display_name' => $support_user->display_name, |
375 | - 'revoke_access_button' => sprintf('<a href="%s" class="button button-danger alignright">%s</a>', $revoke_url, esc_html__('Revoke Access', 'gravityview')), |
|
376 | - 'auth_meta' => sprintf('Created 1 day ago by %s', $auth_meta), |
|
375 | + 'revoke_access_button' => sprintf( '<a href="%s" class="button button-danger alignright">%s</a>', $revoke_url, esc_html__( 'Revoke Access', 'gravityview' ) ), |
|
376 | + 'auth_meta' => sprintf( 'Created 1 day ago by %s', $auth_meta ), |
|
377 | 377 | ]; |
378 | 378 | |
379 | - return $this->prepare_output($template, $content); |
|
379 | + return $this->prepare_output( $template, $content ); |
|
380 | 380 | } |
381 | 381 | |
382 | 382 | /** |
@@ -388,7 +388,7 @@ discard block |
||
388 | 388 | */ |
389 | 389 | public function get_auth_screen() |
390 | 390 | { |
391 | - wp_enqueue_style('trustedlogin-'.$this->config->ns()); |
|
391 | + wp_enqueue_style( 'trustedlogin-' . $this->config->ns() ); |
|
392 | 392 | |
393 | 393 | $content = [ |
394 | 394 | 'ns' => $this->config->ns(), |
@@ -398,8 +398,8 @@ discard block |
||
398 | 398 | 'intro' => $this->get_intro(), |
399 | 399 | 'auth_header' => $this->get_auth_header_html(), |
400 | 400 | 'details' => $this->get_details_html(), |
401 | - 'button' => $this->generate_button('size=hero&class=authlink button-primary', false), |
|
402 | - 'secured_by_trustedlogin' => '<span class="trustedlogin-logo-large"></span>'.esc_html__('Secured by TrustedLogin', 'gravityview'), |
|
401 | + 'button' => $this->generate_button( 'size=hero&class=authlink button-primary', false ), |
|
402 | + 'secured_by_trustedlogin' => '<span class="trustedlogin-logo-large"></span>' . esc_html__( 'Secured by TrustedLogin', 'gravityview' ), |
|
403 | 403 | 'footer' => $this->get_footer_html(), |
404 | 404 | 'reference' => $this->get_reference_html(), |
405 | 405 | ]; |
@@ -435,16 +435,16 @@ discard block |
||
435 | 435 | * |
436 | 436 | * @param string $output_template The Auth form HTML |
437 | 437 | */ |
438 | - $auth_screen_template = apply_filters('trustedlogin/'.$this->config->ns().'/template/auth', $auth_screen_template); |
|
438 | + $auth_screen_template = apply_filters( 'trustedlogin/' . $this->config->ns() . '/template/auth', $auth_screen_template ); |
|
439 | 439 | |
440 | - $output = $this->prepare_output($auth_screen_template, $content); |
|
440 | + $output = $this->prepare_output( $auth_screen_template, $content ); |
|
441 | 441 | |
442 | 442 | return $output; |
443 | 443 | } |
444 | 444 | |
445 | 445 | private function get_header_html() |
446 | 446 | { |
447 | - if ($this->is_login_screen()) { |
|
447 | + if ( $this->is_login_screen() ) { |
|
448 | 448 | return ''; |
449 | 449 | } |
450 | 450 | |
@@ -458,7 +458,7 @@ discard block |
||
458 | 458 | 'logo' => $this->get_logo_html(), |
459 | 459 | ]; |
460 | 460 | |
461 | - return $this->prepare_output($header_template, $variables); |
|
461 | + return $this->prepare_output( $header_template, $variables ); |
|
462 | 462 | } |
463 | 463 | |
464 | 464 | /** |
@@ -468,46 +468,46 @@ discard block |
||
468 | 468 | */ |
469 | 469 | private function get_reference_html() |
470 | 470 | { |
471 | - if (!$this->is_login_screen()) { |
|
471 | + if ( ! $this->is_login_screen() ) { |
|
472 | 472 | return ''; |
473 | 473 | } |
474 | 474 | |
475 | 475 | $reference_id = Client::get_reference_id(); |
476 | 476 | |
477 | - if (null === $reference_id) { |
|
477 | + if ( null === $reference_id ) { |
|
478 | 478 | return ''; |
479 | 479 | } |
480 | 480 | |
481 | 481 | $template = '<div class="tl-{{ns}}-auth__ref"><p><span class="tl-{{ns}}-auth_ref__id">{{reference_text}}</span></p></div>'; |
482 | 482 | |
483 | 483 | $content = [ |
484 | - 'reference_text' => sprintf(esc_html__('Reference #%s', 'gravityview'), $reference_id), |
|
484 | + 'reference_text' => sprintf( esc_html__( 'Reference #%s', 'gravityview' ), $reference_id ), |
|
485 | 485 | 'ns' => $this->config->ns(), |
486 | - 'site_url' => esc_html(str_replace(['https://', 'http://'], '', get_site_url())), |
|
486 | + 'site_url' => esc_html( str_replace( [ 'https://', 'http://' ], '', get_site_url() ) ), |
|
487 | 487 | ]; |
488 | 488 | |
489 | - return $this->prepare_output($template, $content); |
|
489 | + return $this->prepare_output( $template, $content ); |
|
490 | 490 | } |
491 | 491 | |
492 | 492 | private function get_intro() |
493 | 493 | { |
494 | 494 | $has_access = $this->support_user->get_all(); |
495 | 495 | |
496 | - if ($has_access) { |
|
497 | - foreach ($has_access as $access) { |
|
496 | + if ( $has_access ) { |
|
497 | + foreach ( $has_access as $access ) { |
|
498 | 498 | // translators: %1$s is replaced with the name of the software developer (e.g. "Acme Widgets"). %2$s is the amount of time remaining for access ("1 week") |
499 | - $intro = sprintf(esc_html__('%1$s has site access that expires in %2$s.', 'gravityview'), '<a href="'.esc_url($this->config->get_setting('vendor/website')).'" target="_blank" rel="noopener noreferrer">'.$this->config->get_setting('vendor/title').'</a>', str_replace(' ', ' ', $this->support_user->get_expiration($access, true, false))); |
|
499 | + $intro = sprintf( esc_html__( '%1$s has site access that expires in %2$s.', 'gravityview' ), '<a href="' . esc_url( $this->config->get_setting( 'vendor/website' ) ) . '" target="_blank" rel="noopener noreferrer">' . $this->config->get_setting( 'vendor/title' ) . '</a>', str_replace( ' ', ' ', $this->support_user->get_expiration( $access, true, false ) ) ); |
|
500 | 500 | } |
501 | 501 | |
502 | 502 | return $intro; |
503 | 503 | } |
504 | 504 | |
505 | - if ($this->is_login_screen()) { |
|
505 | + if ( $this->is_login_screen() ) { |
|
506 | 506 | // translators: %1$s is replaced with the name of the software developer (e.g. "Acme Widgets") |
507 | - $intro = sprintf(esc_html__('%1$s would like support access to this site.', 'gravityview'), '<a href="'.esc_url($this->config->get_setting('vendor/website')).'">'.$this->config->get_display_name().'</a>'); |
|
507 | + $intro = sprintf( esc_html__( '%1$s would like support access to this site.', 'gravityview' ), '<a href="' . esc_url( $this->config->get_setting( 'vendor/website' ) ) . '">' . $this->config->get_display_name() . '</a>' ); |
|
508 | 508 | } else { |
509 | 509 | // translators: %1$s is replaced with the name of the software developer (e.g. "Acme Widgets") |
510 | - $intro = sprintf(esc_html__('Grant %1$s access to this site.', 'gravityview'), '<a href="'.esc_url($this->config->get_setting('vendor/website')).'">'.$this->config->get_display_name().'</a>'); |
|
510 | + $intro = sprintf( esc_html__( 'Grant %1$s access to this site.', 'gravityview' ), '<a href="' . esc_url( $this->config->get_setting( 'vendor/website' ) ) . '">' . $this->config->get_display_name() . '</a>' ); |
|
511 | 511 | } |
512 | 512 | |
513 | 513 | return $intro; |
@@ -518,14 +518,14 @@ discard block |
||
518 | 518 | $has_access = $this->support_user->get_all(); |
519 | 519 | |
520 | 520 | // Has access |
521 | - if ($has_access) { |
|
521 | + if ( $has_access ) { |
|
522 | 522 | $output_template = ''; |
523 | 523 | $output_template .= '{{users_table}}'; |
524 | 524 | $content = [ |
525 | - 'users_table' => $this->output_support_users(false, ['current_url' => true]), |
|
525 | + 'users_table' => $this->output_support_users( false, [ 'current_url' => true ] ), |
|
526 | 526 | ]; |
527 | 527 | |
528 | - return $this->prepare_output($output_template, $content, false); |
|
528 | + return $this->prepare_output( $output_template, $content, false ); |
|
529 | 529 | } |
530 | 530 | |
531 | 531 | $output_template = ' |
@@ -540,17 +540,17 @@ discard block |
||
540 | 540 | '; |
541 | 541 | |
542 | 542 | // translators: %1$s and %3$s are replaced with HTML tags. %2$s is the amount of time that the login will be active for (e.g. "1 week") |
543 | - $expire_summary = sprintf(esc_html__('Access this site for %s.', 'gravityview'), '<strong>'.human_time_diff(0, $this->config->get_setting('decay')).'</strong>'); |
|
544 | - $expire_desc = '<small>'.sprintf(esc_html__('Access auto-expires in %s. You may revoke access at any time.', 'gravityview'), human_time_diff(0, $this->config->get_setting('decay'))).'</small>'; |
|
543 | + $expire_summary = sprintf( esc_html__( 'Access this site for %s.', 'gravityview' ), '<strong>' . human_time_diff( 0, $this->config->get_setting( 'decay' ) ) . '</strong>' ); |
|
544 | + $expire_desc = '<small>' . sprintf( esc_html__( 'Access auto-expires in %s. You may revoke access at any time.', 'gravityview' ), human_time_diff( 0, $this->config->get_setting( 'decay' ) ) ) . '</small>'; |
|
545 | 545 | |
546 | 546 | $ns = $this->config->ns(); |
547 | - $cloned_role = translate_user_role(ucfirst($this->config->get_setting('role'))); |
|
547 | + $cloned_role = translate_user_role( ucfirst( $this->config->get_setting( 'role' ) ) ); |
|
548 | 548 | |
549 | - if (array_filter($this->config->get_setting('caps'), [$this->config, 'is_not_null'])) { |
|
550 | - $roles_summary = sprintf(esc_html__('Create a user with a role similar to %s.', 'gravityview'), '<strong>'.$cloned_role.'</strong>'); |
|
551 | - $roles_summary .= sprintf('<small class="tl-'.$ns.'-toggle" data-toggle=".tl-'.$ns.'-auth__role-container">%s <span class="dashicons dashicons--small dashicons-arrow-down-alt2"></span></small>', esc_html__('View role capabilities', 'gravityview')); |
|
549 | + if ( array_filter( $this->config->get_setting( 'caps' ), [ $this->config, 'is_not_null' ] ) ) { |
|
550 | + $roles_summary = sprintf( esc_html__( 'Create a user with a role similar to %s.', 'gravityview' ), '<strong>' . $cloned_role . '</strong>' ); |
|
551 | + $roles_summary .= sprintf( '<small class="tl-' . $ns . '-toggle" data-toggle=".tl-' . $ns . '-auth__role-container">%s <span class="dashicons dashicons--small dashicons-arrow-down-alt2"></span></small>', esc_html__( 'View role capabilities', 'gravityview' ) ); |
|
552 | 552 | } else { |
553 | - $roles_summary = sprintf(esc_html__('Create a user with a role of %s.', 'gravityview'), '<strong>'.$cloned_role.'</strong>'); |
|
553 | + $roles_summary = sprintf( esc_html__( 'Create a user with a role of %s.', 'gravityview' ), '<strong>' . $cloned_role . '</strong>' ); |
|
554 | 554 | } |
555 | 555 | |
556 | 556 | $content = [ |
@@ -562,7 +562,7 @@ discard block |
||
562 | 562 | 'caps' => $this->get_caps_html(), |
563 | 563 | ]; |
564 | 564 | |
565 | - return $this->prepare_output($output_template, $content); |
|
565 | + return $this->prepare_output( $output_template, $content ); |
|
566 | 566 | } |
567 | 567 | |
568 | 568 | /** |
@@ -572,18 +572,18 @@ discard block |
||
572 | 572 | */ |
573 | 573 | private function get_caps_html() |
574 | 574 | { |
575 | - $added = $this->config->get_setting('caps/add'); |
|
576 | - $removed = $this->config->get_setting('caps/remove'); |
|
575 | + $added = $this->config->get_setting( 'caps/add' ); |
|
576 | + $removed = $this->config->get_setting( 'caps/remove' ); |
|
577 | 577 | |
578 | 578 | $caps = ''; |
579 | - $caps .= $this->get_caps_section($added, __('Additional capabilities:', 'gravityview'), 'dashicons-yes-alt'); |
|
580 | - $caps .= $this->get_caps_section($removed, __('Removed capabilities:', 'gravityview'), 'dashicons-dismiss'); |
|
579 | + $caps .= $this->get_caps_section( $added, __( 'Additional capabilities:', 'gravityview' ), 'dashicons-yes-alt' ); |
|
580 | + $caps .= $this->get_caps_section( $removed, __( 'Removed capabilities:', 'gravityview' ), 'dashicons-dismiss' ); |
|
581 | 581 | |
582 | - if (empty($caps)) { |
|
582 | + if ( empty( $caps ) ) { |
|
583 | 583 | return $caps; |
584 | 584 | } |
585 | 585 | |
586 | - return '<div class="tl-'.$this->config->ns().'-auth__role-container hidden">'.$caps.'</div>'; |
|
586 | + return '<div class="tl-' . $this->config->ns() . '-auth__role-container hidden">' . $caps . '</div>'; |
|
587 | 587 | } |
588 | 588 | |
589 | 589 | /** |
@@ -595,23 +595,23 @@ discard block |
||
595 | 595 | * |
596 | 596 | * @return string |
597 | 597 | */ |
598 | - private function get_caps_section($caps_array, $heading = '', $dashicon = '') |
|
598 | + private function get_caps_section( $caps_array, $heading = '', $dashicon = '' ) |
|
599 | 599 | { |
600 | - $caps_array = array_filter((array) $caps_array, [$this->config, 'is_not_null']); |
|
600 | + $caps_array = array_filter( (array)$caps_array, [ $this->config, 'is_not_null' ] ); |
|
601 | 601 | |
602 | - if (empty($caps_array)) { |
|
602 | + if ( empty( $caps_array ) ) { |
|
603 | 603 | return ''; |
604 | 604 | } |
605 | 605 | |
606 | 606 | $output = ''; |
607 | 607 | $output .= '<div>'; |
608 | - $output .= '<h3>'.esc_html($heading).'</h3>'; |
|
608 | + $output .= '<h3>' . esc_html( $heading ) . '</h3>'; |
|
609 | 609 | $output .= '<ul>'; |
610 | 610 | |
611 | - foreach ((array) $caps_array as $cap => $reason) { |
|
612 | - $dashicon = '<span class="dashicons '.esc_attr($dashicon).' dashicons--small"></span>'; |
|
613 | - $reason = empty($reason) ? '' : '<small>'.esc_html($reason).'</small>'; |
|
614 | - $output .= sprintf('<li>%s<span class="code">%s</span>%s</li>', $dashicon, esc_html($cap), $reason); |
|
611 | + foreach ( (array)$caps_array as $cap => $reason ) { |
|
612 | + $dashicon = '<span class="dashicons ' . esc_attr( $dashicon ) . ' dashicons--small"></span>'; |
|
613 | + $reason = empty( $reason ) ? '' : '<small>' . esc_html( $reason ) . '</small>'; |
|
614 | + $output .= sprintf( '<li>%s<span class="code">%s</span>%s</li>', $dashicon, esc_html( $cap ), $reason ); |
|
615 | 615 | } |
616 | 616 | |
617 | 617 | $output .= '</ul>'; |
@@ -627,15 +627,15 @@ discard block |
||
627 | 627 | */ |
628 | 628 | private function get_notices_html() |
629 | 629 | { |
630 | - if (!function_exists('wp_get_environment_type')) { |
|
630 | + if ( ! function_exists( 'wp_get_environment_type' ) ) { |
|
631 | 631 | return ''; |
632 | 632 | } |
633 | 633 | |
634 | - if (in_array(wp_get_environment_type(), ['staging', 'production'], true)) { |
|
634 | + if ( in_array( wp_get_environment_type(), [ 'staging', 'production' ], true ) ) { |
|
635 | 635 | return ''; |
636 | 636 | } |
637 | 637 | |
638 | - if (defined('TRUSTEDLOGIN_DISABLE_LOCAL_NOTICE') && TRUSTEDLOGIN_DISABLE_LOCAL_NOTICE) { |
|
638 | + if ( defined( 'TRUSTEDLOGIN_DISABLE_LOCAL_NOTICE' ) && TRUSTEDLOGIN_DISABLE_LOCAL_NOTICE ) { |
|
639 | 639 | return ''; |
640 | 640 | } |
641 | 641 | |
@@ -646,13 +646,13 @@ discard block |
||
646 | 646 | </div>'; |
647 | 647 | |
648 | 648 | $content = [ |
649 | - 'local_site' => sprintf(esc_html__('%s support may not be able to access this site.', 'gravityview'), $this->config->get_setting('vendor/title')), |
|
650 | - 'need_access' => esc_html__('This website is running in a local development environment. To provide support, we must be able to access your site using a publicly-accessible URL.', 'gravityview'), |
|
651 | - 'about_live_access_url' => esc_url($this->config->get_setting('vendor/about_live_access_url', self::ABOUT_LIVE_ACCESS_URL)), |
|
652 | - 'learn_more' => esc_html__('Learn more.', 'gravityview'), |
|
649 | + 'local_site' => sprintf( esc_html__( '%s support may not be able to access this site.', 'gravityview' ), $this->config->get_setting( 'vendor/title' ) ), |
|
650 | + 'need_access' => esc_html__( 'This website is running in a local development environment. To provide support, we must be able to access your site using a publicly-accessible URL.', 'gravityview' ), |
|
651 | + 'about_live_access_url' => esc_url( $this->config->get_setting( 'vendor/about_live_access_url', self::ABOUT_LIVE_ACCESS_URL ) ), |
|
652 | + 'learn_more' => esc_html__( 'Learn more.', 'gravityview' ), |
|
653 | 653 | ]; |
654 | 654 | |
655 | - return $this->prepare_output($notice_template, $content); |
|
655 | + return $this->prepare_output( $notice_template, $content ); |
|
656 | 656 | } |
657 | 657 | |
658 | 658 | /** |
@@ -660,18 +660,18 @@ discard block |
||
660 | 660 | */ |
661 | 661 | private function get_logo_html() |
662 | 662 | { |
663 | - $logo_url = $this->config->get_setting('vendor/logo_url'); |
|
663 | + $logo_url = $this->config->get_setting( 'vendor/logo_url' ); |
|
664 | 664 | |
665 | 665 | $logo_output = ''; |
666 | 666 | |
667 | - if (!empty($logo_url)) { |
|
667 | + if ( ! empty( $logo_url ) ) { |
|
668 | 668 | $logo_output = sprintf( |
669 | 669 | '<a href="%1$s" title="%2$s" target="_blank" rel="noreferrer noopener"><img src="%3$s" alt="%4$s" /></a>', |
670 | - esc_url($this->config->get_setting('vendor/website')), |
|
670 | + esc_url( $this->config->get_setting( 'vendor/website' ) ), |
|
671 | 671 | // translators: %s is replaced with the name of the software developer (e.g. "Acme Widgets") |
672 | - sprintf('Visit the %s website (opens in a new tab)', $this->config->get_setting('vendor/title')), |
|
673 | - esc_attr($this->config->get_setting('vendor/logo_url')), |
|
674 | - esc_attr($this->config->get_setting('vendor/title')) |
|
672 | + sprintf( 'Visit the %s website (opens in a new tab)', $this->config->get_setting( 'vendor/title' ) ), |
|
673 | + esc_attr( $this->config->get_setting( 'vendor/logo_url' ) ), |
|
674 | + esc_attr( $this->config->get_setting( 'vendor/title' ) ) |
|
675 | 675 | ); |
676 | 676 | } |
677 | 677 | |
@@ -685,21 +685,21 @@ discard block |
||
685 | 685 | */ |
686 | 686 | private function get_footer_html() |
687 | 687 | { |
688 | - $support_url = $this->config->get_setting('vendor/support_url'); |
|
688 | + $support_url = $this->config->get_setting( 'vendor/support_url' ); |
|
689 | 689 | |
690 | - if ($reference_id = Client::get_reference_id()) { |
|
690 | + if ( $reference_id = Client::get_reference_id() ) { |
|
691 | 691 | $support_args = [ |
692 | 692 | 'tl' => Client::VERSION, |
693 | 693 | 'ref' => $reference_id, |
694 | 694 | 'ns' => $this->config->ns(), |
695 | 695 | ]; |
696 | 696 | |
697 | - $support_url = add_query_arg($support_args, $support_url); |
|
697 | + $support_url = add_query_arg( $support_args, $support_url ); |
|
698 | 698 | } |
699 | 699 | |
700 | 700 | $footer_links = [ |
701 | - esc_html__('Learn about TrustedLogin', 'gravityview') => self::ABOUT_TL_URL, |
|
702 | - sprintf('Visit %s support', $this->config->get_setting('vendor/title')) => $support_url, |
|
701 | + esc_html__( 'Learn about TrustedLogin', 'gravityview' ) => self::ABOUT_TL_URL, |
|
702 | + sprintf( 'Visit %s support', $this->config->get_setting( 'vendor/title' ) ) => $support_url, |
|
703 | 703 | ]; |
704 | 704 | |
705 | 705 | /** |
@@ -711,115 +711,115 @@ discard block |
||
711 | 711 | * |
712 | 712 | * @param array Array of links to show in auth footer (Key is anchor text; Value is URL) |
713 | 713 | **/ |
714 | - $footer_links = apply_filters('trustedlogin/'.$this->config->ns().'/template/auth/footer_links', $footer_links); |
|
714 | + $footer_links = apply_filters( 'trustedlogin/' . $this->config->ns() . '/template/auth/footer_links', $footer_links ); |
|
715 | 715 | |
716 | 716 | $footer_links_output = ''; |
717 | - foreach ($footer_links as $text => $link) { |
|
717 | + foreach ( $footer_links as $text => $link ) { |
|
718 | 718 | $footer_links_output .= sprintf( |
719 | 719 | '<li><a href="%1$s" target="_blank">%2$s</a></li>', |
720 | - esc_url($link), |
|
721 | - esc_html($text) |
|
720 | + esc_url( $link ), |
|
721 | + esc_html( $text ) |
|
722 | 722 | ); |
723 | 723 | } |
724 | 724 | |
725 | 725 | $footer_output = ''; |
726 | - if (!empty($footer_links_output)) { |
|
727 | - $footer_output = sprintf('<ul>%1$s</ul>', $footer_links_output); |
|
726 | + if ( ! empty( $footer_links_output ) ) { |
|
727 | + $footer_output = sprintf( '<ul>%1$s</ul>', $footer_links_output ); |
|
728 | 728 | } |
729 | 729 | |
730 | 730 | return $footer_output; |
731 | 731 | } |
732 | 732 | |
733 | - private function prepare_output($template, $content, $wp_kses = true) |
|
733 | + private function prepare_output( $template, $content, $wp_kses = true ) |
|
734 | 734 | { |
735 | 735 | $output_html = $template; |
736 | 736 | |
737 | - foreach ($content as $key => $value) { |
|
738 | - $output_html = str_replace('{{'.$key.'}}', $value, $output_html); |
|
737 | + foreach ( $content as $key => $value ) { |
|
738 | + $output_html = str_replace( '{{' . $key . '}}', $value, $output_html ); |
|
739 | 739 | } |
740 | 740 | |
741 | - if ($wp_kses) { |
|
741 | + if ( $wp_kses ) { |
|
742 | 742 | |
743 | 743 | // Allow SVGs for logos |
744 | 744 | $allowed_protocols = wp_allowed_protocols(); |
745 | - $allowed_protocols[] = 'data'; |
|
745 | + $allowed_protocols[ ] = 'data'; |
|
746 | 746 | |
747 | 747 | $output_html = wp_kses( |
748 | 748 | $output_html, |
749 | 749 | [ |
750 | 750 | 'a' => [ |
751 | - 'class' => [], |
|
752 | - 'id' => [], |
|
753 | - 'href' => [], |
|
754 | - 'title' => [], |
|
755 | - 'rel' => [], |
|
756 | - 'target' => [], |
|
757 | - 'data-toggle' => [], |
|
758 | - 'data-access' => [], |
|
751 | + 'class' => [ ], |
|
752 | + 'id' => [ ], |
|
753 | + 'href' => [ ], |
|
754 | + 'title' => [ ], |
|
755 | + 'rel' => [ ], |
|
756 | + 'target' => [ ], |
|
757 | + 'data-toggle' => [ ], |
|
758 | + 'data-access' => [ ], |
|
759 | 759 | ], |
760 | 760 | 'img' => [ |
761 | - 'class' => [], |
|
762 | - 'id' => [], |
|
763 | - 'src' => [], |
|
764 | - 'href' => [], |
|
765 | - 'alt' => [], |
|
766 | - 'title' => [], |
|
761 | + 'class' => [ ], |
|
762 | + 'id' => [ ], |
|
763 | + 'src' => [ ], |
|
764 | + 'href' => [ ], |
|
765 | + 'alt' => [ ], |
|
766 | + 'title' => [ ], |
|
767 | 767 | ], |
768 | 768 | 'span' => [ |
769 | - 'class' => [], |
|
770 | - 'id' => [], |
|
771 | - 'title' => [], |
|
772 | - 'data-toggle' => [], |
|
773 | - 'style' => [], |
|
769 | + 'class' => [ ], |
|
770 | + 'id' => [ ], |
|
771 | + 'title' => [ ], |
|
772 | + 'data-toggle' => [ ], |
|
773 | + 'style' => [ ], |
|
774 | 774 | ], |
775 | - 'label' => ['class' => [], 'id' => [], 'for' => []], |
|
776 | - 'code' => ['class' => [], 'id' => []], |
|
777 | - 'tt' => ['class' => [], 'id' => []], |
|
778 | - 'pre' => ['class' => [], 'id' => []], |
|
779 | - 'table' => ['class' => [], 'id' => []], |
|
780 | - 'thead' => [], |
|
781 | - 'tfoot' => [], |
|
782 | - 'td' => ['class' => [], 'id' => [], 'colspan' => []], |
|
783 | - 'th' => ['class' => [], 'id' => [], 'colspan' => [], 'scope' => []], |
|
784 | - 'ul' => ['class' => [], 'id' => []], |
|
785 | - 'li' => ['class' => [], 'id' => []], |
|
786 | - 'p' => ['class' => [], 'id' => []], |
|
787 | - 'h1' => ['class' => [], 'id' => []], |
|
788 | - 'h2' => ['class' => [], 'id' => []], |
|
789 | - 'h3' => ['class' => [], 'id' => [], 'style' => []], |
|
790 | - 'h4' => ['class' => [], 'id' => []], |
|
791 | - 'h5' => ['class' => [], 'id' => []], |
|
792 | - 'div' => ['class' => [], 'id' => [], 'aria-live' => [], 'style' => []], |
|
793 | - 'small' => ['class' => [], 'id' => [], 'data-toggle' => []], |
|
794 | - 'header' => ['class' => [], 'id' => []], |
|
795 | - 'footer' => ['class' => [], 'id' => []], |
|
796 | - 'section' => ['class' => [], 'id' => []], |
|
797 | - 'br' => [], |
|
798 | - 'strong' => [], |
|
799 | - 'em' => [], |
|
775 | + 'label' => [ 'class' => [ ], 'id' => [ ], 'for' => [ ] ], |
|
776 | + 'code' => [ 'class' => [ ], 'id' => [ ] ], |
|
777 | + 'tt' => [ 'class' => [ ], 'id' => [ ] ], |
|
778 | + 'pre' => [ 'class' => [ ], 'id' => [ ] ], |
|
779 | + 'table' => [ 'class' => [ ], 'id' => [ ] ], |
|
780 | + 'thead' => [ ], |
|
781 | + 'tfoot' => [ ], |
|
782 | + 'td' => [ 'class' => [ ], 'id' => [ ], 'colspan' => [ ] ], |
|
783 | + 'th' => [ 'class' => [ ], 'id' => [ ], 'colspan' => [ ], 'scope' => [ ] ], |
|
784 | + 'ul' => [ 'class' => [ ], 'id' => [ ] ], |
|
785 | + 'li' => [ 'class' => [ ], 'id' => [ ] ], |
|
786 | + 'p' => [ 'class' => [ ], 'id' => [ ] ], |
|
787 | + 'h1' => [ 'class' => [ ], 'id' => [ ] ], |
|
788 | + 'h2' => [ 'class' => [ ], 'id' => [ ] ], |
|
789 | + 'h3' => [ 'class' => [ ], 'id' => [ ], 'style' => [ ] ], |
|
790 | + 'h4' => [ 'class' => [ ], 'id' => [ ] ], |
|
791 | + 'h5' => [ 'class' => [ ], 'id' => [ ] ], |
|
792 | + 'div' => [ 'class' => [ ], 'id' => [ ], 'aria-live' => [ ], 'style' => [ ] ], |
|
793 | + 'small' => [ 'class' => [ ], 'id' => [ ], 'data-toggle' => [ ] ], |
|
794 | + 'header' => [ 'class' => [ ], 'id' => [ ] ], |
|
795 | + 'footer' => [ 'class' => [ ], 'id' => [ ] ], |
|
796 | + 'section' => [ 'class' => [ ], 'id' => [ ] ], |
|
797 | + 'br' => [ ], |
|
798 | + 'strong' => [ ], |
|
799 | + 'em' => [ ], |
|
800 | 800 | 'input' => [ |
801 | - 'class' => [], |
|
802 | - 'id' => [], |
|
803 | - 'type' => ['text'], |
|
804 | - 'value' => [], |
|
805 | - 'size' => [], |
|
806 | - 'aria-live' => [], |
|
807 | - 'aria-label' => [], |
|
808 | - 'style' => [], |
|
801 | + 'class' => [ ], |
|
802 | + 'id' => [ ], |
|
803 | + 'type' => [ 'text' ], |
|
804 | + 'value' => [ ], |
|
805 | + 'size' => [ ], |
|
806 | + 'aria-live' => [ ], |
|
807 | + 'aria-label' => [ ], |
|
808 | + 'style' => [ ], |
|
809 | 809 | ], |
810 | 810 | 'button' => [ |
811 | - 'class' => [], |
|
812 | - 'id' => [], |
|
813 | - 'aria-live' => [], |
|
814 | - 'style' => [], |
|
815 | - 'title' => [], |
|
811 | + 'class' => [ ], |
|
812 | + 'id' => [ ], |
|
813 | + 'aria-live' => [ ], |
|
814 | + 'style' => [ ], |
|
815 | + 'title' => [ ], |
|
816 | 816 | ], |
817 | 817 | ], |
818 | 818 | $allowed_protocols |
819 | 819 | ); |
820 | 820 | } |
821 | 821 | |
822 | - return normalize_whitespace($output_html); |
|
822 | + return normalize_whitespace( $output_html ); |
|
823 | 823 | } |
824 | 824 | |
825 | 825 | /** |
@@ -832,44 +832,44 @@ discard block |
||
832 | 832 | * |
833 | 833 | * @return string the HTML output |
834 | 834 | */ |
835 | - public function generate_button($atts = [], $print = true) |
|
835 | + public function generate_button( $atts = [ ], $print = true ) |
|
836 | 836 | { |
837 | - if (!current_user_can('create_users')) { |
|
837 | + if ( ! current_user_can( 'create_users' ) ) { |
|
838 | 838 | return ''; |
839 | 839 | } |
840 | 840 | |
841 | - if (!wp_script_is('trustedlogin-'.$this->config->ns(), 'registered')) { |
|
842 | - $this->logging->log('JavaScript is not registered. Make sure `trustedlogin` handle is added to "no-conflict" plugin settings.', __METHOD__, 'error'); |
|
841 | + if ( ! wp_script_is( 'trustedlogin-' . $this->config->ns(), 'registered' ) ) { |
|
842 | + $this->logging->log( 'JavaScript is not registered. Make sure `trustedlogin` handle is added to "no-conflict" plugin settings.', __METHOD__, 'error' ); |
|
843 | 843 | } |
844 | 844 | |
845 | - if (!wp_style_is('trustedlogin-'.$this->config->ns(), 'registered')) { |
|
846 | - $this->logging->log('Style is not registered. Make sure `trustedlogin` handle is added to "no-conflict" plugin settings.', __METHOD__, 'error'); |
|
845 | + if ( ! wp_style_is( 'trustedlogin-' . $this->config->ns(), 'registered' ) ) { |
|
846 | + $this->logging->log( 'Style is not registered. Make sure `trustedlogin` handle is added to "no-conflict" plugin settings.', __METHOD__, 'error' ); |
|
847 | 847 | } |
848 | 848 | |
849 | - wp_enqueue_style('trustedlogin-'.$this->config->ns()); |
|
849 | + wp_enqueue_style( 'trustedlogin-' . $this->config->ns() ); |
|
850 | 850 | |
851 | 851 | $button_settings = [ |
852 | - 'vendor' => $this->config->get_setting('vendor'), |
|
853 | - 'ajaxurl' => admin_url('admin-ajax.php'), |
|
854 | - '_nonce' => wp_create_nonce('tl_nonce-'.get_current_user_id()), |
|
852 | + 'vendor' => $this->config->get_setting( 'vendor' ), |
|
853 | + 'ajaxurl' => admin_url( 'admin-ajax.php' ), |
|
854 | + '_nonce' => wp_create_nonce( 'tl_nonce-' . get_current_user_id() ), |
|
855 | 855 | 'lang' => $this->translations(), |
856 | 856 | 'debug' => $this->logging->is_enabled(), |
857 | - 'selector' => '.button-trustedlogin-'.$this->config->ns(), |
|
857 | + 'selector' => '.button-trustedlogin-' . $this->config->ns(), |
|
858 | 858 | 'reference_id' => Client::get_reference_id(), |
859 | - 'query_string' => esc_url(remove_query_arg([ |
|
859 | + 'query_string' => esc_url( remove_query_arg( [ |
|
860 | 860 | Endpoint::REVOKE_SUPPORT_QUERY_PARAM, |
861 | 861 | '_wpnonce', |
862 | - ])), |
|
862 | + ] ) ), |
|
863 | 863 | ]; |
864 | 864 | |
865 | 865 | // TODO: Add data to tl_obj when detecting that it's already been localized by another vendor |
866 | - wp_localize_script('trustedlogin-'.$this->config->ns(), 'tl_obj', $button_settings); |
|
866 | + wp_localize_script( 'trustedlogin-' . $this->config->ns(), 'tl_obj', $button_settings ); |
|
867 | 867 | |
868 | - wp_enqueue_script('trustedlogin-'.$this->config->ns()); |
|
868 | + wp_enqueue_script( 'trustedlogin-' . $this->config->ns() ); |
|
869 | 869 | |
870 | - $return = $this->get_button($atts); |
|
870 | + $return = $this->get_button( $atts ); |
|
871 | 871 | |
872 | - if ($print) { |
|
872 | + if ( $print ) { |
|
873 | 873 | echo $return; |
874 | 874 | } |
875 | 875 | |
@@ -895,23 +895,23 @@ discard block |
||
895 | 895 | * |
896 | 896 | * @return string |
897 | 897 | */ |
898 | - public function get_button($atts = []) |
|
898 | + public function get_button( $atts = [ ] ) |
|
899 | 899 | { |
900 | 900 | $defaults = [ |
901 | - 'text' => sprintf(esc_html__('Grant %s Access', 'gravityview'), $this->config->get_display_name()), |
|
902 | - 'exists_text' => sprintf(esc_html__('Extend %s Access', 'gravityview'), $this->config->get_display_name(), ucwords(human_time_diff(time(), time() + $this->config->get_setting('decay')))), |
|
901 | + 'text' => sprintf( esc_html__( 'Grant %s Access', 'gravityview' ), $this->config->get_display_name() ), |
|
902 | + 'exists_text' => sprintf( esc_html__( 'Extend %s Access', 'gravityview' ), $this->config->get_display_name(), ucwords( human_time_diff( time(), time() + $this->config->get_setting( 'decay' ) ) ) ), |
|
903 | 903 | 'size' => 'hero', |
904 | 904 | 'class' => 'button-primary', |
905 | 905 | 'tag' => 'a', // "a", "button", "span" |
906 | 906 | 'powered_by' => false, |
907 | - 'support_url' => $this->config->get_setting('vendor/support_url'), |
|
907 | + 'support_url' => $this->config->get_setting( 'vendor/support_url' ), |
|
908 | 908 | ]; |
909 | 909 | |
910 | - $sizes = ['small', 'normal', 'large', 'hero']; |
|
910 | + $sizes = [ 'small', 'normal', 'large', 'hero' ]; |
|
911 | 911 | |
912 | - $atts = wp_parse_args($atts, $defaults); |
|
912 | + $atts = wp_parse_args( $atts, $defaults ); |
|
913 | 913 | |
914 | - switch ($atts['size']) { |
|
914 | + switch ( $atts[ 'size' ] ) { |
|
915 | 915 | case '': |
916 | 916 | $css_class = ''; |
917 | 917 | break; |
@@ -919,59 +919,59 @@ discard block |
||
919 | 919 | $css_class = 'button'; |
920 | 920 | break; |
921 | 921 | default: |
922 | - if (!in_array($atts['size'], $sizes)) { |
|
923 | - $atts['size'] = 'hero'; |
|
922 | + if ( ! in_array( $atts[ 'size' ], $sizes ) ) { |
|
923 | + $atts[ 'size' ] = 'hero'; |
|
924 | 924 | } |
925 | 925 | |
926 | - $css_class = 'button button-'.$atts['size']; |
|
926 | + $css_class = 'button button-' . $atts[ 'size' ]; |
|
927 | 927 | } |
928 | 928 | |
929 | - $_valid_tags = ['a', 'button', 'span']; |
|
929 | + $_valid_tags = [ 'a', 'button', 'span' ]; |
|
930 | 930 | |
931 | - if (!empty($atts['tag']) && in_array(strtolower($atts['tag']), $_valid_tags, true)) { |
|
932 | - $tag = $atts['tag']; |
|
931 | + if ( ! empty( $atts[ 'tag' ] ) && in_array( strtolower( $atts[ 'tag' ] ), $_valid_tags, true ) ) { |
|
932 | + $tag = $atts[ 'tag' ]; |
|
933 | 933 | } else { |
934 | 934 | $tag = 'a'; |
935 | 935 | } |
936 | 936 | |
937 | - $data_atts = []; |
|
937 | + $data_atts = [ ]; |
|
938 | 938 | |
939 | - if ($this->support_user->get_all()) { |
|
940 | - $text = '<span class="dashicons dashicons-update-alt"></span>'.esc_html($atts['exists_text']); |
|
941 | - $href = admin_url('users.php?role='.$this->support_user->role->get_name()); |
|
942 | - $data_atts['access'] = 'extend'; |
|
939 | + if ( $this->support_user->get_all() ) { |
|
940 | + $text = '<span class="dashicons dashicons-update-alt"></span>' . esc_html( $atts[ 'exists_text' ] ); |
|
941 | + $href = admin_url( 'users.php?role=' . $this->support_user->role->get_name() ); |
|
942 | + $data_atts[ 'access' ] = 'extend'; |
|
943 | 943 | } else { |
944 | - $text = esc_html($atts['text']); |
|
945 | - $href = $atts['support_url']; |
|
946 | - $data_atts['access'] = 'grant'; |
|
944 | + $text = esc_html( $atts[ 'text' ] ); |
|
945 | + $href = $atts[ 'support_url' ]; |
|
946 | + $data_atts[ 'access' ] = 'grant'; |
|
947 | 947 | } |
948 | 948 | |
949 | - $css_class = implode(' ', [$css_class, $atts['class']]); |
|
950 | - $css_class = trim($css_class); |
|
949 | + $css_class = implode( ' ', [ $css_class, $atts[ 'class' ] ] ); |
|
950 | + $css_class = trim( $css_class ); |
|
951 | 951 | |
952 | 952 | $data_string = ''; |
953 | - foreach ($data_atts as $key => $value) { |
|
954 | - $data_string .= sprintf(' data-%s="%s"', esc_attr($key), esc_attr($value)); |
|
953 | + foreach ( $data_atts as $key => $value ) { |
|
954 | + $data_string .= sprintf( ' data-%s="%s"', esc_attr( $key ), esc_attr( $value ) ); |
|
955 | 955 | } |
956 | 956 | |
957 | 957 | $powered_by = ''; |
958 | - if ($atts['powered_by']) { |
|
958 | + if ( $atts[ 'powered_by' ] ) { |
|
959 | 959 | $powered_by = sprintf( |
960 | 960 | '<small><span class="trustedlogin-logo"></span>%s</small>', |
961 | - esc_html__('Secured by TrustedLogin', 'gravityview') |
|
961 | + esc_html__( 'Secured by TrustedLogin', 'gravityview' ) |
|
962 | 962 | ); |
963 | 963 | } |
964 | 964 | |
965 | - $anchor_html = $text.$powered_by; |
|
965 | + $anchor_html = $text . $powered_by; |
|
966 | 966 | |
967 | 967 | return sprintf( |
968 | 968 | '<%1$s href="%2$s" class="%3$s button-trustedlogin-%4$s" aria-role="button" %5$s>%6$s</%1$s>', |
969 | 969 | /* %1$s */ |
970 | 970 | $tag, |
971 | 971 | /* %2$s */ |
972 | - esc_url($href), |
|
972 | + esc_url( $href ), |
|
973 | 973 | /* %3$s */ |
974 | - esc_attr($css_class), |
|
974 | + esc_attr( $css_class ), |
|
975 | 975 | /* %4$s */ |
976 | 976 | $this->config->ns(), |
977 | 977 | /* %5$s */ |
@@ -990,7 +990,7 @@ discard block |
||
990 | 990 | */ |
991 | 991 | public function translations() |
992 | 992 | { |
993 | - $vendor_title = $this->config->get_setting('vendor/title'); |
|
993 | + $vendor_title = $this->config->get_setting( 'vendor/title' ); |
|
994 | 994 | |
995 | 995 | /** |
996 | 996 | * Filter: Allow for adding into GET parameters on support_url. |
@@ -1010,9 +1010,9 @@ discard block |
||
1010 | 1010 | * } |
1011 | 1011 | */ |
1012 | 1012 | $query_args = apply_filters( |
1013 | - 'trustedlogin/'.$this->config->ns().'/support_url/query_args', |
|
1013 | + 'trustedlogin/' . $this->config->ns() . '/support_url/query_args', |
|
1014 | 1014 | [ |
1015 | - 'message' => __('Could not create TrustedLogin access.', 'gravityview'), |
|
1015 | + 'message' => __( 'Could not create TrustedLogin access.', 'gravityview' ), |
|
1016 | 1016 | 'ref' => Client::get_reference_id(), |
1017 | 1017 | ] |
1018 | 1018 | ); |
@@ -1020,97 +1020,97 @@ discard block |
||
1020 | 1020 | $error_content = sprintf( |
1021 | 1021 | '<p>%s</p><p>%s</p>', |
1022 | 1022 | sprintf( |
1023 | - esc_html__('The user details could not be sent to %1$s automatically.', 'gravityview'), |
|
1023 | + esc_html__( 'The user details could not be sent to %1$s automatically.', 'gravityview' ), |
|
1024 | 1024 | $vendor_title |
1025 | 1025 | ), |
1026 | 1026 | sprintf( |
1027 | - __('Please <a href="%1$s" target="_blank">click here</a> to go to the %2$s support site', 'gravityview'), |
|
1028 | - esc_url(add_query_arg($query_args, $this->config->get_setting('vendor/support_url'))), |
|
1027 | + __( 'Please <a href="%1$s" target="_blank">click here</a> to go to the %2$s support site', 'gravityview' ), |
|
1028 | + esc_url( add_query_arg( $query_args, $this->config->get_setting( 'vendor/support_url' ) ) ), |
|
1029 | 1029 | $vendor_title |
1030 | 1030 | ) |
1031 | 1031 | ); |
1032 | 1032 | |
1033 | 1033 | $translations = [ |
1034 | 1034 | 'buttons' => [ |
1035 | - 'confirm' => esc_html__('Confirm', 'gravityview'), |
|
1036 | - 'ok' => esc_html__('Ok', 'gravityview'), |
|
1037 | - 'go_to_site' => sprintf(__('Go to %1$s support site', 'gravityview'), $vendor_title), |
|
1038 | - 'close' => esc_html__('Close', 'gravityview'), |
|
1039 | - 'cancel' => esc_html__('Cancel', 'gravityview'), |
|
1040 | - 'revoke' => sprintf(esc_html__('Revoke %1$s support access', 'gravityview'), $vendor_title), |
|
1041 | - 'copy' => esc_html__('Copy', 'gravityview'), |
|
1042 | - 'copied' => esc_html__('Copied!', 'gravityview'), |
|
1035 | + 'confirm' => esc_html__( 'Confirm', 'gravityview' ), |
|
1036 | + 'ok' => esc_html__( 'Ok', 'gravityview' ), |
|
1037 | + 'go_to_site' => sprintf( __( 'Go to %1$s support site', 'gravityview' ), $vendor_title ), |
|
1038 | + 'close' => esc_html__( 'Close', 'gravityview' ), |
|
1039 | + 'cancel' => esc_html__( 'Cancel', 'gravityview' ), |
|
1040 | + 'revoke' => sprintf( esc_html__( 'Revoke %1$s support access', 'gravityview' ), $vendor_title ), |
|
1041 | + 'copy' => esc_html__( 'Copy', 'gravityview' ), |
|
1042 | + 'copied' => esc_html__( 'Copied!', 'gravityview' ), |
|
1043 | 1043 | ], |
1044 | 1044 | 'a11y' => [ |
1045 | - 'opens_new_window' => esc_attr__('(This link opens in a new window.)', 'gravityview'), |
|
1046 | - 'copied_text' => esc_html__('The access key has been copied to your clipboard.', 'gravityview'), |
|
1045 | + 'opens_new_window' => esc_attr__( '(This link opens in a new window.)', 'gravityview' ), |
|
1046 | + 'copied_text' => esc_html__( 'The access key has been copied to your clipboard.', 'gravityview' ), |
|
1047 | 1047 | ], |
1048 | 1048 | 'status' => [ |
1049 | 1049 | 'synced' => [ |
1050 | - 'title' => esc_html__('Support access granted', 'gravityview'), |
|
1050 | + 'title' => esc_html__( 'Support access granted', 'gravityview' ), |
|
1051 | 1051 | 'content' => sprintf( |
1052 | - __('A temporary support user has been created, and sent to %1$s support.', 'gravityview'), |
|
1052 | + __( 'A temporary support user has been created, and sent to %1$s support.', 'gravityview' ), |
|
1053 | 1053 | $vendor_title |
1054 | 1054 | ), |
1055 | 1055 | ], |
1056 | 1056 | 'pending' => [ |
1057 | - 'content' => sprintf(__('Generating & encrypting secure support access for %1$s', 'gravityview'), $vendor_title), |
|
1057 | + 'content' => sprintf( __( 'Generating & encrypting secure support access for %1$s', 'gravityview' ), $vendor_title ), |
|
1058 | 1058 | ], |
1059 | 1059 | 'extending' => [ |
1060 | - 'content' => sprintf(__('Extending support access for %1$s by %2$s', 'gravityview'), $vendor_title, human_time_diff(time(), time() + $this->config->get_setting('decay'))), |
|
1060 | + 'content' => sprintf( __( 'Extending support access for %1$s by %2$s', 'gravityview' ), $vendor_title, human_time_diff( time(), time() + $this->config->get_setting( 'decay' ) ) ), |
|
1061 | 1061 | ], |
1062 | 1062 | 'syncing' => [ |
1063 | - 'content' => sprintf(__('Sending encrypted access to %1$s.', 'gravityview'), $vendor_title), |
|
1063 | + 'content' => sprintf( __( 'Sending encrypted access to %1$s.', 'gravityview' ), $vendor_title ), |
|
1064 | 1064 | ], |
1065 | 1065 | 'error' => [ |
1066 | - 'title' => sprintf(__('Error syncing support user to %1$s', 'gravityview'), $vendor_title), |
|
1067 | - 'content' => wp_kses($error_content, [ |
|
1066 | + 'title' => sprintf( __( 'Error syncing support user to %1$s', 'gravityview' ), $vendor_title ), |
|
1067 | + 'content' => wp_kses( $error_content, [ |
|
1068 | 1068 | 'a' => [ |
1069 | - 'href' => [], |
|
1070 | - 'rel' => [], |
|
1071 | - 'target' => [], |
|
1069 | + 'href' => [ ], |
|
1070 | + 'rel' => [ ], |
|
1071 | + 'target' => [ ], |
|
1072 | 1072 | ], |
1073 | - 'p' => [], |
|
1074 | - ]), |
|
1073 | + 'p' => [ ], |
|
1074 | + ] ), |
|
1075 | 1075 | ], |
1076 | 1076 | 'cancel' => [ |
1077 | - 'title' => esc_html__('Action Cancelled', 'gravityview'), |
|
1077 | + 'title' => esc_html__( 'Action Cancelled', 'gravityview' ), |
|
1078 | 1078 | 'content' => sprintf( |
1079 | - __('A support account for %1$s was not created.', 'gravityview'), |
|
1079 | + __( 'A support account for %1$s was not created.', 'gravityview' ), |
|
1080 | 1080 | $vendor_title |
1081 | 1081 | ), |
1082 | 1082 | ], |
1083 | 1083 | 'failed' => [ |
1084 | - 'title' => esc_html__('Support Access Was Not Granted', 'gravityview'), |
|
1085 | - 'content' => esc_html__('There was an error granting access: ', 'gravityview'), |
|
1084 | + 'title' => esc_html__( 'Support Access Was Not Granted', 'gravityview' ), |
|
1085 | + 'content' => esc_html__( 'There was an error granting access: ', 'gravityview' ), |
|
1086 | 1086 | ], |
1087 | 1087 | 'failed_permissions' => [ |
1088 | - 'content' => esc_html__('Your authorized session has expired. Please refresh the page.', 'gravityview'), |
|
1088 | + 'content' => esc_html__( 'Your authorized session has expired. Please refresh the page.', 'gravityview' ), |
|
1089 | 1089 | ], |
1090 | 1090 | 'accesskey' => [ |
1091 | - 'title' => esc_html__('TrustedLogin Key Created', 'gravityview'), |
|
1091 | + 'title' => esc_html__( 'TrustedLogin Key Created', 'gravityview' ), |
|
1092 | 1092 | 'content' => sprintf( |
1093 | - __('Share this TrustedLogin Key with %1$s to give them secure access:', 'gravityview'), |
|
1093 | + __( 'Share this TrustedLogin Key with %1$s to give them secure access:', 'gravityview' ), |
|
1094 | 1094 | $vendor_title |
1095 | 1095 | ), |
1096 | - 'revoke_link' => esc_url(add_query_arg([Endpoint::REVOKE_SUPPORT_QUERY_PARAM => $this->config->ns()], admin_url())), |
|
1096 | + 'revoke_link' => esc_url( add_query_arg( [ Endpoint::REVOKE_SUPPORT_QUERY_PARAM => $this->config->ns() ], admin_url() ) ), |
|
1097 | 1097 | ], |
1098 | 1098 | 'error404' => [ |
1099 | - 'title' => esc_html__('The TrustedLogin vendor could not be found.', 'gravityview'), |
|
1099 | + 'title' => esc_html__( 'The TrustedLogin vendor could not be found.', 'gravityview' ), |
|
1100 | 1100 | 'content' => '', |
1101 | 1101 | ], |
1102 | 1102 | 'error409' => [ |
1103 | 1103 | 'title' => sprintf( |
1104 | - __('%1$s Support user already exists', 'gravityview'), |
|
1104 | + __( '%1$s Support user already exists', 'gravityview' ), |
|
1105 | 1105 | $vendor_title |
1106 | 1106 | ), |
1107 | 1107 | 'content' => sprintf( |
1108 | 1108 | wp_kses( |
1109 | - __('A support user for %1$s already exists. You may revoke this support access from your <a href="%2$s" target="_blank">Users list</a>.', 'gravityview'), |
|
1110 | - ['a' => ['href' => [], 'target' => []]] |
|
1109 | + __( 'A support user for %1$s already exists. You may revoke this support access from your <a href="%2$s" target="_blank">Users list</a>.', 'gravityview' ), |
|
1110 | + [ 'a' => [ 'href' => [ ], 'target' => [ ] ] ] |
|
1111 | 1111 | ), |
1112 | 1112 | $vendor_title, |
1113 | - esc_url(admin_url('users.php?role='.$this->support_user->role->get_name())) |
|
1113 | + esc_url( admin_url( 'users.php?role=' . $this->support_user->role->get_name() ) ) |
|
1114 | 1114 | ), |
1115 | 1115 | ], |
1116 | 1116 | ], |
@@ -1132,23 +1132,23 @@ discard block |
||
1132 | 1132 | * |
1133 | 1133 | * @return string HTML table of active support users for vendor. Empty string if current user can't `create_users` |
1134 | 1134 | */ |
1135 | - public function output_support_users($print = true, $atts = []) |
|
1135 | + public function output_support_users( $print = true, $atts = [ ] ) |
|
1136 | 1136 | { |
1137 | - if ((!is_admin() && !$this->is_login_screen()) || !current_user_can('create_users')) { |
|
1137 | + if ( ( ! is_admin() && ! $this->is_login_screen() ) || ! current_user_can( 'create_users' ) ) { |
|
1138 | 1138 | return ''; |
1139 | 1139 | } |
1140 | 1140 | |
1141 | 1141 | // The `trustedlogin/{$ns}/button` action passes an empty string |
1142 | - if ('' === $print) { |
|
1142 | + if ( '' === $print ) { |
|
1143 | 1143 | $print = true; |
1144 | 1144 | } |
1145 | 1145 | |
1146 | 1146 | $support_users = $this->support_user->get_all(); |
1147 | 1147 | |
1148 | - if (empty($support_users)) { |
|
1149 | - $return = '<h3>'.sprintf(esc_html__('No %s users exist.', 'gravityview'), $this->config->get_setting('vendor/title')).'</h3>'; |
|
1148 | + if ( empty( $support_users ) ) { |
|
1149 | + $return = '<h3>' . sprintf( esc_html__( 'No %s users exist.', 'gravityview' ), $this->config->get_setting( 'vendor/title' ) ) . '</h3>'; |
|
1150 | 1150 | |
1151 | - if ($print) { |
|
1151 | + if ( $print ) { |
|
1152 | 1152 | echo $return; |
1153 | 1153 | } |
1154 | 1154 | |
@@ -1159,7 +1159,7 @@ discard block |
||
1159 | 1159 | 'current_url' => false, |
1160 | 1160 | ]; |
1161 | 1161 | |
1162 | - $atts = wp_parse_args($atts, $default_atts); |
|
1162 | + $atts = wp_parse_args( $atts, $default_atts ); |
|
1163 | 1163 | |
1164 | 1164 | $return = ''; |
1165 | 1165 | |
@@ -1178,25 +1178,25 @@ discard block |
||
1178 | 1178 | $access_key_output = sprintf( |
1179 | 1179 | $access_key_template, |
1180 | 1180 | /* %1$s */ |
1181 | - sanitize_title($this->config->ns()), |
|
1181 | + sanitize_title( $this->config->ns() ), |
|
1182 | 1182 | /* %2$s */ |
1183 | - esc_html__('Site access key:', 'gravityview'), |
|
1183 | + esc_html__( 'Site access key:', 'gravityview' ), |
|
1184 | 1184 | /* %3$s */ |
1185 | - esc_html__('Access Key', 'gravityview'), |
|
1185 | + esc_html__( 'Access Key', 'gravityview' ), |
|
1186 | 1186 | /* %4$s */ |
1187 | - esc_attr($this->site_access->get_access_key()), |
|
1187 | + esc_attr( $this->site_access->get_access_key() ), |
|
1188 | 1188 | /* %5$s */ |
1189 | - esc_html__('Copy', 'gravityview'), |
|
1189 | + esc_html__( 'Copy', 'gravityview' ), |
|
1190 | 1190 | /* %6$s */ |
1191 | 1191 | 'div', |
1192 | 1192 | /* %7$s */ |
1193 | - esc_html__('Copy the access key to your clipboard', 'gravityview'), |
|
1194 | - sprintf('The access key is not a password; only %1$s will be able to access your site using this code. You may share this access key on support forums.', $this->support_user->get_first()->display_name) |
|
1193 | + esc_html__( 'Copy the access key to your clipboard', 'gravityview' ), |
|
1194 | + sprintf( 'The access key is not a password; only %1$s will be able to access your site using this code. You may share this access key on support forums.', $this->support_user->get_first()->display_name ) |
|
1195 | 1195 | ); |
1196 | 1196 | |
1197 | 1197 | $return .= $access_key_output; |
1198 | 1198 | |
1199 | - if ($print) { |
|
1199 | + if ( $print ) { |
|
1200 | 1200 | echo $return; |
1201 | 1201 | } |
1202 | 1202 | |
@@ -1210,7 +1210,7 @@ discard block |
||
1210 | 1210 | */ |
1211 | 1211 | public function admin_notices() |
1212 | 1212 | { |
1213 | - add_action('admin_notices', [$this, 'admin_notice_revoked']); |
|
1213 | + add_action( 'admin_notices', [ $this, 'admin_notice_revoked' ] ); |
|
1214 | 1214 | } |
1215 | 1215 | |
1216 | 1216 | /** |
@@ -1223,13 +1223,13 @@ discard block |
||
1223 | 1223 | static $displayed_notice; |
1224 | 1224 | |
1225 | 1225 | // Only show notice once |
1226 | - if ($displayed_notice) { |
|
1226 | + if ( $displayed_notice ) { |
|
1227 | 1227 | return; |
1228 | 1228 | } ?> |
1229 | 1229 | <div class="notice notice-success is-dismissible"> |
1230 | - <h3><?php echo esc_html(sprintf(__('%s access revoked.', 'gravityview'), $this->config->get_setting('vendor/title'))); ?></h3> |
|
1231 | - <?php if (!current_user_can('delete_users')) { ?> |
|
1232 | - <p><?php echo esc_html__('You may safely close this window.', 'gravityview'); ?></p> |
|
1230 | + <h3><?php echo esc_html( sprintf( __( '%s access revoked.', 'gravityview' ), $this->config->get_setting( 'vendor/title' ) ) ); ?></h3> |
|
1231 | + <?php if ( ! current_user_can( 'delete_users' ) ) { ?> |
|
1232 | + <p><?php echo esc_html__( 'You may safely close this window.', 'gravityview' ); ?></p> |
|
1233 | 1233 | <?php } ?> |
1234 | 1234 | </div> |
1235 | 1235 | <?php |
@@ -23,8 +23,7 @@ discard block |
||
23 | 23 | use WP_Admin_Bar; |
24 | 24 | use WP_User; |
25 | 25 | |
26 | -final class Admin |
|
27 | -{ |
|
26 | +final class Admin { |
|
28 | 27 | /** |
29 | 28 | * URL pointing to the "About TrustedLogin" page, shown below the Grant Access dialog. |
30 | 29 | */ |
@@ -57,16 +56,14 @@ discard block |
||
57 | 56 | * |
58 | 57 | * @param Config $config |
59 | 58 | */ |
60 | - public function __construct(Config $config, Logging $logging) |
|
61 | - { |
|
59 | + public function __construct(Config $config, Logging $logging) { |
|
62 | 60 | $this->config = $config; |
63 | 61 | $this->logging = $logging; |
64 | 62 | $this->site_access = new SiteAccess($config, $logging); |
65 | 63 | $this->support_user = new SupportUser($config, $logging); |
66 | 64 | } |
67 | 65 | |
68 | - public function init() |
|
69 | - { |
|
66 | + public function init() { |
|
70 | 67 | add_action('trustedlogin/'.$this->config->ns().'/button', [$this, 'generate_button'], 10, 2); |
71 | 68 | add_action('trustedlogin/'.$this->config->ns().'/users_table', [ |
72 | 69 | $this, |
@@ -100,8 +97,7 @@ discard block |
||
100 | 97 | * |
101 | 98 | * @return array |
102 | 99 | */ |
103 | - public function user_row_action_revoke($actions, $user_object) |
|
104 | - { |
|
100 | + public function user_row_action_revoke($actions, $user_object) { |
|
105 | 101 | if (!current_user_can($this->support_user->role->get_name()) && !current_user_can('delete_users')) { |
106 | 102 | return $actions; |
107 | 103 | } |
@@ -122,8 +118,7 @@ discard block |
||
122 | 118 | * |
123 | 119 | * @since 1.0.0 |
124 | 120 | */ |
125 | - public function register_assets() |
|
126 | - { |
|
121 | + public function register_assets() { |
|
127 | 122 | $registered = []; |
128 | 123 | |
129 | 124 | $registered['trustedlogin-js'] = wp_register_script( |
@@ -156,8 +151,7 @@ discard block |
||
156 | 151 | * |
157 | 152 | * @return void |
158 | 153 | */ |
159 | - public function admin_bar_add_toolbar_items($admin_bar) |
|
160 | - { |
|
154 | + public function admin_bar_add_toolbar_items($admin_bar) { |
|
161 | 155 | if (!current_user_can($this->support_user->role->get_name())) { |
162 | 156 | return; |
163 | 157 | } |
@@ -201,8 +195,7 @@ discard block |
||
201 | 195 | * |
202 | 196 | * @return void |
203 | 197 | */ |
204 | - public function admin_menu_auth_link_page() |
|
205 | - { |
|
198 | + public function admin_menu_auth_link_page() { |
|
206 | 199 | $parent_slug = $this->config->get_setting('menu/slug', null); |
207 | 200 | |
208 | 201 | // When false, there will be no menus added. |
@@ -247,8 +240,7 @@ discard block |
||
247 | 240 | * |
248 | 241 | * @return bool |
249 | 242 | */ |
250 | - private function is_login_screen() |
|
251 | - { |
|
243 | + private function is_login_screen() { |
|
252 | 244 | return did_action('login_init') && isset($_GET['ns']) && $_GET['ns'] === $this->config->ns(); |
253 | 245 | } |
254 | 246 | |
@@ -257,8 +249,7 @@ discard block |
||
257 | 249 | * |
258 | 250 | * @return void |
259 | 251 | */ |
260 | - public function maybe_print_request_screen() |
|
261 | - { |
|
252 | + public function maybe_print_request_screen() { |
|
262 | 253 | if (!$this->is_login_screen()) { |
263 | 254 | return; |
264 | 255 | } |
@@ -277,8 +268,7 @@ discard block |
||
277 | 268 | $this->print_request_screen(); |
278 | 269 | } |
279 | 270 | |
280 | - public function print_request_screen() |
|
281 | - { |
|
271 | + public function print_request_screen() { |
|
282 | 272 | global $interim_login, $wp_version; |
283 | 273 | |
284 | 274 | // Don't output a "← Back to site" link on the login page |
@@ -315,8 +305,7 @@ discard block |
||
315 | 305 | * |
316 | 306 | * @return string |
317 | 307 | */ |
318 | - private function get_login_inline_css() |
|
319 | - { |
|
308 | + private function get_login_inline_css() { |
|
320 | 309 | return ' |
321 | 310 | #login { |
322 | 311 | width: auto; |
@@ -341,13 +330,11 @@ discard block |
||
341 | 330 | * |
342 | 331 | * @return void |
343 | 332 | */ |
344 | - public function print_auth_screen() |
|
345 | - { |
|
333 | + public function print_auth_screen() { |
|
346 | 334 | echo $this->get_auth_screen(); |
347 | 335 | } |
348 | 336 | |
349 | - public function get_auth_header_html() |
|
350 | - { |
|
337 | + public function get_auth_header_html() { |
|
351 | 338 | $support_users = $this->support_user->get_all(); |
352 | 339 | |
353 | 340 | if (empty($support_users)) { |
@@ -386,8 +373,7 @@ discard block |
||
386 | 373 | * |
387 | 374 | * @return string HTML of the Auth screen |
388 | 375 | */ |
389 | - public function get_auth_screen() |
|
390 | - { |
|
376 | + public function get_auth_screen() { |
|
391 | 377 | wp_enqueue_style('trustedlogin-'.$this->config->ns()); |
392 | 378 | |
393 | 379 | $content = [ |
@@ -442,8 +428,7 @@ discard block |
||
442 | 428 | return $output; |
443 | 429 | } |
444 | 430 | |
445 | - private function get_header_html() |
|
446 | - { |
|
431 | + private function get_header_html() { |
|
447 | 432 | if ($this->is_login_screen()) { |
448 | 433 | return ''; |
449 | 434 | } |
@@ -466,8 +451,7 @@ discard block |
||
466 | 451 | * |
467 | 452 | * @return string |
468 | 453 | */ |
469 | - private function get_reference_html() |
|
470 | - { |
|
454 | + private function get_reference_html() { |
|
471 | 455 | if (!$this->is_login_screen()) { |
472 | 456 | return ''; |
473 | 457 | } |
@@ -489,8 +473,7 @@ discard block |
||
489 | 473 | return $this->prepare_output($template, $content); |
490 | 474 | } |
491 | 475 | |
492 | - private function get_intro() |
|
493 | - { |
|
476 | + private function get_intro() { |
|
494 | 477 | $has_access = $this->support_user->get_all(); |
495 | 478 | |
496 | 479 | if ($has_access) { |
@@ -513,8 +496,7 @@ discard block |
||
513 | 496 | return $intro; |
514 | 497 | } |
515 | 498 | |
516 | - private function get_details_html() |
|
517 | - { |
|
499 | + private function get_details_html() { |
|
518 | 500 | $has_access = $this->support_user->get_all(); |
519 | 501 | |
520 | 502 | // Has access |
@@ -570,8 +552,7 @@ discard block |
||
570 | 552 | * |
571 | 553 | * @return string Empty string if there are no caps defined. Otherwise, HTML of caps in lists. |
572 | 554 | */ |
573 | - private function get_caps_html() |
|
574 | - { |
|
555 | + private function get_caps_html() { |
|
575 | 556 | $added = $this->config->get_setting('caps/add'); |
576 | 557 | $removed = $this->config->get_setting('caps/remove'); |
577 | 558 | |
@@ -595,8 +576,7 @@ discard block |
||
595 | 576 | * |
596 | 577 | * @return string |
597 | 578 | */ |
598 | - private function get_caps_section($caps_array, $heading = '', $dashicon = '') |
|
599 | - { |
|
579 | + private function get_caps_section($caps_array, $heading = '', $dashicon = '') { |
|
600 | 580 | $caps_array = array_filter((array) $caps_array, [$this->config, 'is_not_null']); |
601 | 581 | |
602 | 582 | if (empty($caps_array)) { |
@@ -625,8 +605,7 @@ discard block |
||
625 | 605 | * |
626 | 606 | * @return string |
627 | 607 | */ |
628 | - private function get_notices_html() |
|
629 | - { |
|
608 | + private function get_notices_html() { |
|
630 | 609 | if (!function_exists('wp_get_environment_type')) { |
631 | 610 | return ''; |
632 | 611 | } |
@@ -658,8 +637,7 @@ discard block |
||
658 | 637 | /** |
659 | 638 | * @return string |
660 | 639 | */ |
661 | - private function get_logo_html() |
|
662 | - { |
|
640 | + private function get_logo_html() { |
|
663 | 641 | $logo_url = $this->config->get_setting('vendor/logo_url'); |
664 | 642 | |
665 | 643 | $logo_output = ''; |
@@ -683,8 +661,7 @@ discard block |
||
683 | 661 | * |
684 | 662 | * @return string |
685 | 663 | */ |
686 | - private function get_footer_html() |
|
687 | - { |
|
664 | + private function get_footer_html() { |
|
688 | 665 | $support_url = $this->config->get_setting('vendor/support_url'); |
689 | 666 | |
690 | 667 | if ($reference_id = Client::get_reference_id()) { |
@@ -730,8 +707,7 @@ discard block |
||
730 | 707 | return $footer_output; |
731 | 708 | } |
732 | 709 | |
733 | - private function prepare_output($template, $content, $wp_kses = true) |
|
734 | - { |
|
710 | + private function prepare_output($template, $content, $wp_kses = true) { |
|
735 | 711 | $output_html = $template; |
736 | 712 | |
737 | 713 | foreach ($content as $key => $value) { |
@@ -832,8 +808,7 @@ discard block |
||
832 | 808 | * |
833 | 809 | * @return string the HTML output |
834 | 810 | */ |
835 | - public function generate_button($atts = [], $print = true) |
|
836 | - { |
|
811 | + public function generate_button($atts = [], $print = true) { |
|
837 | 812 | if (!current_user_can('create_users')) { |
838 | 813 | return ''; |
839 | 814 | } |
@@ -895,8 +870,7 @@ discard block |
||
895 | 870 | * |
896 | 871 | * @return string |
897 | 872 | */ |
898 | - public function get_button($atts = []) |
|
899 | - { |
|
873 | + public function get_button($atts = []) { |
|
900 | 874 | $defaults = [ |
901 | 875 | 'text' => sprintf(esc_html__('Grant %s Access', 'gravityview'), $this->config->get_display_name()), |
902 | 876 | 'exists_text' => sprintf(esc_html__('Extend %s Access', 'gravityview'), $this->config->get_display_name(), ucwords(human_time_diff(time(), time() + $this->config->get_setting('decay')))), |
@@ -988,8 +962,7 @@ discard block |
||
988 | 962 | * |
989 | 963 | * @return array of Translations and strings to be localized to JS variables |
990 | 964 | */ |
991 | - public function translations() |
|
992 | - { |
|
965 | + public function translations() { |
|
993 | 966 | $vendor_title = $this->config->get_setting('vendor/title'); |
994 | 967 | |
995 | 968 | /** |
@@ -1132,8 +1105,7 @@ discard block |
||
1132 | 1105 | * |
1133 | 1106 | * @return string HTML table of active support users for vendor. Empty string if current user can't `create_users` |
1134 | 1107 | */ |
1135 | - public function output_support_users($print = true, $atts = []) |
|
1136 | - { |
|
1108 | + public function output_support_users($print = true, $atts = []) { |
|
1137 | 1109 | if ((!is_admin() && !$this->is_login_screen()) || !current_user_can('create_users')) { |
1138 | 1110 | return ''; |
1139 | 1111 | } |
@@ -1208,8 +1180,7 @@ discard block |
||
1208 | 1180 | * |
1209 | 1181 | * @return void |
1210 | 1182 | */ |
1211 | - public function admin_notices() |
|
1212 | - { |
|
1183 | + public function admin_notices() { |
|
1213 | 1184 | add_action('admin_notices', [$this, 'admin_notice_revoked']); |
1214 | 1185 | } |
1215 | 1186 | |
@@ -1218,8 +1189,7 @@ discard block |
||
1218 | 1189 | * |
1219 | 1190 | * @return void |
1220 | 1191 | */ |
1221 | - public function admin_notice_revoked() |
|
1222 | - { |
|
1192 | + public function admin_notice_revoked() { |
|
1223 | 1193 | static $displayed_notice; |
1224 | 1194 | |
1225 | 1195 | // Only show notice once |
@@ -1173,7 +1173,7 @@ |
||
1173 | 1173 | <button id="tl-%1$s-copy" class="tl-%1$s-auth__accesskey_copy button" aria-live="off" title="%7$s"><span class="screen-reader-text">%5$s</span></button> |
1174 | 1174 | </div> |
1175 | 1175 | </%6$s> |
1176 | -EOD; |
|
1176 | +eod; |
|
1177 | 1177 | |
1178 | 1178 | $access_key_output = sprintf( |
1179 | 1179 | $access_key_template, |
@@ -16,212 +16,212 @@ |
||
16 | 16 | |
17 | 17 | class SiteAccess |
18 | 18 | { |
19 | - /** |
|
20 | - * @var Config |
|
21 | - */ |
|
22 | - private $config; |
|
23 | - |
|
24 | - /** |
|
25 | - * @var Logging |
|
26 | - */ |
|
27 | - private $logging; |
|
28 | - |
|
29 | - /** |
|
30 | - * @var string[] Valid action types to use when syncing to TrustedLogin. |
|
31 | - */ |
|
32 | - private static $sync_actions = [ |
|
33 | - 'create', |
|
34 | - 'extend', |
|
35 | - ]; |
|
36 | - |
|
37 | - public function __construct(Config $config, Logging $logging) |
|
38 | - { |
|
39 | - $this->config = $config; |
|
40 | - $this->logging = $logging; |
|
41 | - } |
|
42 | - |
|
43 | - /** |
|
44 | - * Handles the syncing of newly generated support access to the TrustedLogin servers. |
|
45 | - * |
|
46 | - * @param string $secret_id The unique identifier for this TrustedLogin authorization. {@see Endpoint::generate_secret_id} |
|
47 | - * @param string $site_identifier_hash The unique identifier for the WP_User created {@see Encryption::get_random_hash()} |
|
48 | - * @param string $action The type of sync this is. Options can be 'create', 'extend'. |
|
49 | - * |
|
50 | - * @return true|WP_Error True if successfully created secret on TrustedLogin servers; WP_Error if failed. |
|
51 | - */ |
|
52 | - public function sync_secret($secret_id, $site_identifier_hash, $action = 'create') |
|
53 | - { |
|
54 | - $logging = new Logging($this->config); |
|
55 | - $remote = new Remote($this->config, $logging); |
|
56 | - $encryption = new Encryption($this->config, $remote, $logging); |
|
57 | - |
|
58 | - if (!in_array($action, self::$sync_actions, true)) { |
|
59 | - return new WP_Error('param_error', __('Unexpected action value', 'gravityview')); |
|
60 | - } |
|
61 | - |
|
62 | - $access_key = $this->get_access_key(); |
|
63 | - |
|
64 | - if (is_wp_error($access_key)) { |
|
65 | - return $access_key; |
|
66 | - } |
|
67 | - |
|
68 | - // Ping SaaS and get back tokens. |
|
69 | - $envelope = new Envelope($this->config, $encryption); |
|
70 | - |
|
71 | - $sealed_envelope = $envelope->get($secret_id, $site_identifier_hash, $access_key); |
|
72 | - |
|
73 | - if (is_wp_error($sealed_envelope)) { |
|
74 | - return $sealed_envelope; |
|
75 | - } |
|
76 | - |
|
77 | - $api_response = $remote->send('sites', $sealed_envelope, 'POST'); |
|
78 | - |
|
79 | - if (is_wp_error($api_response)) { |
|
80 | - return $api_response; |
|
81 | - } |
|
82 | - |
|
83 | - $response_json = $remote->handle_response($api_response, ['success']); |
|
84 | - |
|
85 | - if (is_wp_error($response_json)) { |
|
86 | - return $response_json; |
|
87 | - } |
|
88 | - |
|
89 | - if (empty($response_json['success'])) { |
|
90 | - return new WP_Error('sync_error', __('Could not sync to TrustedLogin server', 'gravityview')); |
|
91 | - } |
|
92 | - |
|
93 | - do_action('trustedlogin/'.$this->config->ns().'/secret/synced', [ |
|
94 | - 'url' => get_site_url(), |
|
95 | - 'action' => $action, |
|
96 | - ]); |
|
97 | - |
|
98 | - return true; |
|
99 | - } |
|
100 | - |
|
101 | - /** |
|
102 | - * Gets the shareable access key. |
|
103 | - * |
|
104 | - * - For licensed plugins or themes, a hashed customer's license key is the access key. |
|
105 | - * - For plugins or themes without license keys, the accessKey is generated for the site. |
|
106 | - * |
|
107 | - * @uses SiteAccess::get_license_key() |
|
108 | - * @uses SiteAccess::generate_access_key() |
|
109 | - * |
|
110 | - * @since 1.0.0 |
|
111 | - * |
|
112 | - * @return string|null $access_key, if exists. Either a hashed license key or a generated hash. If error occurs, returns null. |
|
113 | - */ |
|
114 | - public function get_access_key() |
|
115 | - { |
|
116 | - |
|
117 | - // If there's a license, return a hash of the license. |
|
118 | - $license_key = $this->get_license_key(true); |
|
119 | - |
|
120 | - if ($license_key && !is_wp_error($license_key)) { |
|
121 | - return $license_key; |
|
122 | - } |
|
123 | - |
|
124 | - $generated_access_key = $this->generate_access_key(); |
|
125 | - |
|
126 | - if (!$generated_access_key || is_wp_error($generated_access_key)) { |
|
127 | - return null; |
|
128 | - } |
|
129 | - |
|
130 | - return $generated_access_key; |
|
131 | - } |
|
132 | - |
|
133 | - /** |
|
134 | - * Get the license key for the current user. |
|
135 | - * |
|
136 | - * @since 1.0.0 |
|
137 | - * |
|
138 | - * @param bool $hashed Should the value be hashed using SHA256? |
|
139 | - * |
|
140 | - * @return string|null|WP_Error License key (hashed if $hashed is true) or null if not found. Returns WP_Error if error occurs. |
|
141 | - */ |
|
142 | - public function get_license_key($hashed = false) |
|
143 | - { |
|
144 | - |
|
145 | - // If no license key is provided |
|
146 | - $license_key_config = $this->config->get_setting('auth/license_key', null); |
|
147 | - |
|
148 | - /** |
|
149 | - * Filter: Allow for over-riding the 'accessKey' sent to SaaS platform. |
|
150 | - * |
|
151 | - * @since 1.0.0 |
|
152 | - * |
|
153 | - * @param string|null $license_key |
|
154 | - */ |
|
155 | - $license_key = apply_filters('trustedlogin/'.$this->config->ns().'/licence_key', $license_key_config); |
|
156 | - |
|
157 | - if (!is_string($license_key)) { |
|
158 | - $this->logging->log('', '', 'error', [ |
|
159 | - '$license from Config' => $license_key_config, |
|
160 | - '$license after filter: ' => $license_key, |
|
161 | - ]); |
|
162 | - |
|
163 | - return new WP_Error('invalid_license_key', 'License key was not a string.'); |
|
164 | - } |
|
165 | - |
|
166 | - if ($hashed && $license_key) { |
|
167 | - return hash('sha256', $license_key); |
|
168 | - } |
|
169 | - |
|
170 | - return empty($license_key) ? null : $license_key; |
|
171 | - } |
|
172 | - |
|
173 | - /** |
|
174 | - * Generates an accessKey that can be copy-pasted to support to give them access via TrustedLogin. |
|
175 | - * |
|
176 | - * Access Keys can only be used by authenticated support agents to request logged access to a site via their TrustedLogin plugin. |
|
177 | - * |
|
178 | - * @since 1.0.0 |
|
179 | - * |
|
180 | - * @return string|WP_Error Access Key prepended with TL, or something went wrong. |
|
181 | - */ |
|
182 | - private function generate_access_key() |
|
183 | - { |
|
184 | - $hash = Encryption::hash(get_current_blog_id().get_site_url().$this->config->get_setting('auth/api_key'), 32); |
|
185 | - |
|
186 | - if (is_wp_error($hash)) { |
|
187 | - return $hash; |
|
188 | - } |
|
189 | - |
|
190 | - return $hash; |
|
191 | - } |
|
192 | - |
|
193 | - /** |
|
194 | - * Revoke a site in TrustedLogin. |
|
195 | - * |
|
196 | - * @param string $secret_id ID of site secret identifier to be removed from TrustedLogin |
|
197 | - * @param Remote $remote |
|
198 | - * |
|
199 | - * @return true|\WP_Error Was the sync to TrustedLogin successful |
|
200 | - */ |
|
201 | - public function revoke($secret_id, Remote $remote) |
|
202 | - { |
|
203 | - if (!$this->config->meets_ssl_requirement()) { |
|
204 | - $this->logging->log('Not notifying TrustedLogin about revoked site due to SSL requirements.', __METHOD__, 'info'); |
|
205 | - |
|
206 | - return true; |
|
207 | - } |
|
208 | - |
|
209 | - $body = [ |
|
210 | - 'publicKey' => $this->config->get_setting('auth/api_key'), |
|
211 | - ]; |
|
212 | - |
|
213 | - $api_response = $remote->send('sites/'.$secret_id, $body, 'DELETE'); |
|
214 | - |
|
215 | - if (is_wp_error($api_response)) { |
|
216 | - return $api_response; |
|
217 | - } |
|
218 | - |
|
219 | - $response = $remote->handle_response($api_response); |
|
220 | - |
|
221 | - if (is_wp_error($response)) { |
|
222 | - return $response; |
|
223 | - } |
|
224 | - |
|
225 | - return true; |
|
226 | - } |
|
19 | + /** |
|
20 | + * @var Config |
|
21 | + */ |
|
22 | + private $config; |
|
23 | + |
|
24 | + /** |
|
25 | + * @var Logging |
|
26 | + */ |
|
27 | + private $logging; |
|
28 | + |
|
29 | + /** |
|
30 | + * @var string[] Valid action types to use when syncing to TrustedLogin. |
|
31 | + */ |
|
32 | + private static $sync_actions = [ |
|
33 | + 'create', |
|
34 | + 'extend', |
|
35 | + ]; |
|
36 | + |
|
37 | + public function __construct(Config $config, Logging $logging) |
|
38 | + { |
|
39 | + $this->config = $config; |
|
40 | + $this->logging = $logging; |
|
41 | + } |
|
42 | + |
|
43 | + /** |
|
44 | + * Handles the syncing of newly generated support access to the TrustedLogin servers. |
|
45 | + * |
|
46 | + * @param string $secret_id The unique identifier for this TrustedLogin authorization. {@see Endpoint::generate_secret_id} |
|
47 | + * @param string $site_identifier_hash The unique identifier for the WP_User created {@see Encryption::get_random_hash()} |
|
48 | + * @param string $action The type of sync this is. Options can be 'create', 'extend'. |
|
49 | + * |
|
50 | + * @return true|WP_Error True if successfully created secret on TrustedLogin servers; WP_Error if failed. |
|
51 | + */ |
|
52 | + public function sync_secret($secret_id, $site_identifier_hash, $action = 'create') |
|
53 | + { |
|
54 | + $logging = new Logging($this->config); |
|
55 | + $remote = new Remote($this->config, $logging); |
|
56 | + $encryption = new Encryption($this->config, $remote, $logging); |
|
57 | + |
|
58 | + if (!in_array($action, self::$sync_actions, true)) { |
|
59 | + return new WP_Error('param_error', __('Unexpected action value', 'gravityview')); |
|
60 | + } |
|
61 | + |
|
62 | + $access_key = $this->get_access_key(); |
|
63 | + |
|
64 | + if (is_wp_error($access_key)) { |
|
65 | + return $access_key; |
|
66 | + } |
|
67 | + |
|
68 | + // Ping SaaS and get back tokens. |
|
69 | + $envelope = new Envelope($this->config, $encryption); |
|
70 | + |
|
71 | + $sealed_envelope = $envelope->get($secret_id, $site_identifier_hash, $access_key); |
|
72 | + |
|
73 | + if (is_wp_error($sealed_envelope)) { |
|
74 | + return $sealed_envelope; |
|
75 | + } |
|
76 | + |
|
77 | + $api_response = $remote->send('sites', $sealed_envelope, 'POST'); |
|
78 | + |
|
79 | + if (is_wp_error($api_response)) { |
|
80 | + return $api_response; |
|
81 | + } |
|
82 | + |
|
83 | + $response_json = $remote->handle_response($api_response, ['success']); |
|
84 | + |
|
85 | + if (is_wp_error($response_json)) { |
|
86 | + return $response_json; |
|
87 | + } |
|
88 | + |
|
89 | + if (empty($response_json['success'])) { |
|
90 | + return new WP_Error('sync_error', __('Could not sync to TrustedLogin server', 'gravityview')); |
|
91 | + } |
|
92 | + |
|
93 | + do_action('trustedlogin/'.$this->config->ns().'/secret/synced', [ |
|
94 | + 'url' => get_site_url(), |
|
95 | + 'action' => $action, |
|
96 | + ]); |
|
97 | + |
|
98 | + return true; |
|
99 | + } |
|
100 | + |
|
101 | + /** |
|
102 | + * Gets the shareable access key. |
|
103 | + * |
|
104 | + * - For licensed plugins or themes, a hashed customer's license key is the access key. |
|
105 | + * - For plugins or themes without license keys, the accessKey is generated for the site. |
|
106 | + * |
|
107 | + * @uses SiteAccess::get_license_key() |
|
108 | + * @uses SiteAccess::generate_access_key() |
|
109 | + * |
|
110 | + * @since 1.0.0 |
|
111 | + * |
|
112 | + * @return string|null $access_key, if exists. Either a hashed license key or a generated hash. If error occurs, returns null. |
|
113 | + */ |
|
114 | + public function get_access_key() |
|
115 | + { |
|
116 | + |
|
117 | + // If there's a license, return a hash of the license. |
|
118 | + $license_key = $this->get_license_key(true); |
|
119 | + |
|
120 | + if ($license_key && !is_wp_error($license_key)) { |
|
121 | + return $license_key; |
|
122 | + } |
|
123 | + |
|
124 | + $generated_access_key = $this->generate_access_key(); |
|
125 | + |
|
126 | + if (!$generated_access_key || is_wp_error($generated_access_key)) { |
|
127 | + return null; |
|
128 | + } |
|
129 | + |
|
130 | + return $generated_access_key; |
|
131 | + } |
|
132 | + |
|
133 | + /** |
|
134 | + * Get the license key for the current user. |
|
135 | + * |
|
136 | + * @since 1.0.0 |
|
137 | + * |
|
138 | + * @param bool $hashed Should the value be hashed using SHA256? |
|
139 | + * |
|
140 | + * @return string|null|WP_Error License key (hashed if $hashed is true) or null if not found. Returns WP_Error if error occurs. |
|
141 | + */ |
|
142 | + public function get_license_key($hashed = false) |
|
143 | + { |
|
144 | + |
|
145 | + // If no license key is provided |
|
146 | + $license_key_config = $this->config->get_setting('auth/license_key', null); |
|
147 | + |
|
148 | + /** |
|
149 | + * Filter: Allow for over-riding the 'accessKey' sent to SaaS platform. |
|
150 | + * |
|
151 | + * @since 1.0.0 |
|
152 | + * |
|
153 | + * @param string|null $license_key |
|
154 | + */ |
|
155 | + $license_key = apply_filters('trustedlogin/'.$this->config->ns().'/licence_key', $license_key_config); |
|
156 | + |
|
157 | + if (!is_string($license_key)) { |
|
158 | + $this->logging->log('', '', 'error', [ |
|
159 | + '$license from Config' => $license_key_config, |
|
160 | + '$license after filter: ' => $license_key, |
|
161 | + ]); |
|
162 | + |
|
163 | + return new WP_Error('invalid_license_key', 'License key was not a string.'); |
|
164 | + } |
|
165 | + |
|
166 | + if ($hashed && $license_key) { |
|
167 | + return hash('sha256', $license_key); |
|
168 | + } |
|
169 | + |
|
170 | + return empty($license_key) ? null : $license_key; |
|
171 | + } |
|
172 | + |
|
173 | + /** |
|
174 | + * Generates an accessKey that can be copy-pasted to support to give them access via TrustedLogin. |
|
175 | + * |
|
176 | + * Access Keys can only be used by authenticated support agents to request logged access to a site via their TrustedLogin plugin. |
|
177 | + * |
|
178 | + * @since 1.0.0 |
|
179 | + * |
|
180 | + * @return string|WP_Error Access Key prepended with TL, or something went wrong. |
|
181 | + */ |
|
182 | + private function generate_access_key() |
|
183 | + { |
|
184 | + $hash = Encryption::hash(get_current_blog_id().get_site_url().$this->config->get_setting('auth/api_key'), 32); |
|
185 | + |
|
186 | + if (is_wp_error($hash)) { |
|
187 | + return $hash; |
|
188 | + } |
|
189 | + |
|
190 | + return $hash; |
|
191 | + } |
|
192 | + |
|
193 | + /** |
|
194 | + * Revoke a site in TrustedLogin. |
|
195 | + * |
|
196 | + * @param string $secret_id ID of site secret identifier to be removed from TrustedLogin |
|
197 | + * @param Remote $remote |
|
198 | + * |
|
199 | + * @return true|\WP_Error Was the sync to TrustedLogin successful |
|
200 | + */ |
|
201 | + public function revoke($secret_id, Remote $remote) |
|
202 | + { |
|
203 | + if (!$this->config->meets_ssl_requirement()) { |
|
204 | + $this->logging->log('Not notifying TrustedLogin about revoked site due to SSL requirements.', __METHOD__, 'info'); |
|
205 | + |
|
206 | + return true; |
|
207 | + } |
|
208 | + |
|
209 | + $body = [ |
|
210 | + 'publicKey' => $this->config->get_setting('auth/api_key'), |
|
211 | + ]; |
|
212 | + |
|
213 | + $api_response = $remote->send('sites/'.$secret_id, $body, 'DELETE'); |
|
214 | + |
|
215 | + if (is_wp_error($api_response)) { |
|
216 | + return $api_response; |
|
217 | + } |
|
218 | + |
|
219 | + $response = $remote->handle_response($api_response); |
|
220 | + |
|
221 | + if (is_wp_error($response)) { |
|
222 | + return $response; |
|
223 | + } |
|
224 | + |
|
225 | + return true; |
|
226 | + } |
|
227 | 227 | } |
@@ -34,7 +34,7 @@ discard block |
||
34 | 34 | 'extend', |
35 | 35 | ]; |
36 | 36 | |
37 | - public function __construct(Config $config, Logging $logging) |
|
37 | + public function __construct( Config $config, Logging $logging ) |
|
38 | 38 | { |
39 | 39 | $this->config = $config; |
40 | 40 | $this->logging = $logging; |
@@ -49,51 +49,51 @@ discard block |
||
49 | 49 | * |
50 | 50 | * @return true|WP_Error True if successfully created secret on TrustedLogin servers; WP_Error if failed. |
51 | 51 | */ |
52 | - public function sync_secret($secret_id, $site_identifier_hash, $action = 'create') |
|
52 | + public function sync_secret( $secret_id, $site_identifier_hash, $action = 'create' ) |
|
53 | 53 | { |
54 | - $logging = new Logging($this->config); |
|
55 | - $remote = new Remote($this->config, $logging); |
|
56 | - $encryption = new Encryption($this->config, $remote, $logging); |
|
54 | + $logging = new Logging( $this->config ); |
|
55 | + $remote = new Remote( $this->config, $logging ); |
|
56 | + $encryption = new Encryption( $this->config, $remote, $logging ); |
|
57 | 57 | |
58 | - if (!in_array($action, self::$sync_actions, true)) { |
|
59 | - return new WP_Error('param_error', __('Unexpected action value', 'gravityview')); |
|
58 | + if ( ! in_array( $action, self::$sync_actions, true ) ) { |
|
59 | + return new WP_Error( 'param_error', __( 'Unexpected action value', 'gravityview' ) ); |
|
60 | 60 | } |
61 | 61 | |
62 | 62 | $access_key = $this->get_access_key(); |
63 | 63 | |
64 | - if (is_wp_error($access_key)) { |
|
64 | + if ( is_wp_error( $access_key ) ) { |
|
65 | 65 | return $access_key; |
66 | 66 | } |
67 | 67 | |
68 | 68 | // Ping SaaS and get back tokens. |
69 | - $envelope = new Envelope($this->config, $encryption); |
|
69 | + $envelope = new Envelope( $this->config, $encryption ); |
|
70 | 70 | |
71 | - $sealed_envelope = $envelope->get($secret_id, $site_identifier_hash, $access_key); |
|
71 | + $sealed_envelope = $envelope->get( $secret_id, $site_identifier_hash, $access_key ); |
|
72 | 72 | |
73 | - if (is_wp_error($sealed_envelope)) { |
|
73 | + if ( is_wp_error( $sealed_envelope ) ) { |
|
74 | 74 | return $sealed_envelope; |
75 | 75 | } |
76 | 76 | |
77 | - $api_response = $remote->send('sites', $sealed_envelope, 'POST'); |
|
77 | + $api_response = $remote->send( 'sites', $sealed_envelope, 'POST' ); |
|
78 | 78 | |
79 | - if (is_wp_error($api_response)) { |
|
79 | + if ( is_wp_error( $api_response ) ) { |
|
80 | 80 | return $api_response; |
81 | 81 | } |
82 | 82 | |
83 | - $response_json = $remote->handle_response($api_response, ['success']); |
|
83 | + $response_json = $remote->handle_response( $api_response, [ 'success' ] ); |
|
84 | 84 | |
85 | - if (is_wp_error($response_json)) { |
|
85 | + if ( is_wp_error( $response_json ) ) { |
|
86 | 86 | return $response_json; |
87 | 87 | } |
88 | 88 | |
89 | - if (empty($response_json['success'])) { |
|
90 | - return new WP_Error('sync_error', __('Could not sync to TrustedLogin server', 'gravityview')); |
|
89 | + if ( empty( $response_json[ 'success' ] ) ) { |
|
90 | + return new WP_Error( 'sync_error', __( 'Could not sync to TrustedLogin server', 'gravityview' ) ); |
|
91 | 91 | } |
92 | 92 | |
93 | - do_action('trustedlogin/'.$this->config->ns().'/secret/synced', [ |
|
93 | + do_action( 'trustedlogin/' . $this->config->ns() . '/secret/synced', [ |
|
94 | 94 | 'url' => get_site_url(), |
95 | 95 | 'action' => $action, |
96 | - ]); |
|
96 | + ] ); |
|
97 | 97 | |
98 | 98 | return true; |
99 | 99 | } |
@@ -115,15 +115,15 @@ discard block |
||
115 | 115 | { |
116 | 116 | |
117 | 117 | // If there's a license, return a hash of the license. |
118 | - $license_key = $this->get_license_key(true); |
|
118 | + $license_key = $this->get_license_key( true ); |
|
119 | 119 | |
120 | - if ($license_key && !is_wp_error($license_key)) { |
|
120 | + if ( $license_key && ! is_wp_error( $license_key ) ) { |
|
121 | 121 | return $license_key; |
122 | 122 | } |
123 | 123 | |
124 | 124 | $generated_access_key = $this->generate_access_key(); |
125 | 125 | |
126 | - if (!$generated_access_key || is_wp_error($generated_access_key)) { |
|
126 | + if ( ! $generated_access_key || is_wp_error( $generated_access_key ) ) { |
|
127 | 127 | return null; |
128 | 128 | } |
129 | 129 | |
@@ -139,11 +139,11 @@ discard block |
||
139 | 139 | * |
140 | 140 | * @return string|null|WP_Error License key (hashed if $hashed is true) or null if not found. Returns WP_Error if error occurs. |
141 | 141 | */ |
142 | - public function get_license_key($hashed = false) |
|
142 | + public function get_license_key( $hashed = false ) |
|
143 | 143 | { |
144 | 144 | |
145 | 145 | // If no license key is provided |
146 | - $license_key_config = $this->config->get_setting('auth/license_key', null); |
|
146 | + $license_key_config = $this->config->get_setting( 'auth/license_key', null ); |
|
147 | 147 | |
148 | 148 | /** |
149 | 149 | * Filter: Allow for over-riding the 'accessKey' sent to SaaS platform. |
@@ -152,22 +152,22 @@ discard block |
||
152 | 152 | * |
153 | 153 | * @param string|null $license_key |
154 | 154 | */ |
155 | - $license_key = apply_filters('trustedlogin/'.$this->config->ns().'/licence_key', $license_key_config); |
|
155 | + $license_key = apply_filters( 'trustedlogin/' . $this->config->ns() . '/licence_key', $license_key_config ); |
|
156 | 156 | |
157 | - if (!is_string($license_key)) { |
|
158 | - $this->logging->log('', '', 'error', [ |
|
157 | + if ( ! is_string( $license_key ) ) { |
|
158 | + $this->logging->log( '', '', 'error', [ |
|
159 | 159 | '$license from Config' => $license_key_config, |
160 | 160 | '$license after filter: ' => $license_key, |
161 | - ]); |
|
161 | + ] ); |
|
162 | 162 | |
163 | - return new WP_Error('invalid_license_key', 'License key was not a string.'); |
|
163 | + return new WP_Error( 'invalid_license_key', 'License key was not a string.' ); |
|
164 | 164 | } |
165 | 165 | |
166 | - if ($hashed && $license_key) { |
|
167 | - return hash('sha256', $license_key); |
|
166 | + if ( $hashed && $license_key ) { |
|
167 | + return hash( 'sha256', $license_key ); |
|
168 | 168 | } |
169 | 169 | |
170 | - return empty($license_key) ? null : $license_key; |
|
170 | + return empty( $license_key ) ? null : $license_key; |
|
171 | 171 | } |
172 | 172 | |
173 | 173 | /** |
@@ -181,9 +181,9 @@ discard block |
||
181 | 181 | */ |
182 | 182 | private function generate_access_key() |
183 | 183 | { |
184 | - $hash = Encryption::hash(get_current_blog_id().get_site_url().$this->config->get_setting('auth/api_key'), 32); |
|
184 | + $hash = Encryption::hash( get_current_blog_id() . get_site_url() . $this->config->get_setting( 'auth/api_key' ), 32 ); |
|
185 | 185 | |
186 | - if (is_wp_error($hash)) { |
|
186 | + if ( is_wp_error( $hash ) ) { |
|
187 | 187 | return $hash; |
188 | 188 | } |
189 | 189 | |
@@ -198,27 +198,27 @@ discard block |
||
198 | 198 | * |
199 | 199 | * @return true|\WP_Error Was the sync to TrustedLogin successful |
200 | 200 | */ |
201 | - public function revoke($secret_id, Remote $remote) |
|
201 | + public function revoke( $secret_id, Remote $remote ) |
|
202 | 202 | { |
203 | - if (!$this->config->meets_ssl_requirement()) { |
|
204 | - $this->logging->log('Not notifying TrustedLogin about revoked site due to SSL requirements.', __METHOD__, 'info'); |
|
203 | + if ( ! $this->config->meets_ssl_requirement() ) { |
|
204 | + $this->logging->log( 'Not notifying TrustedLogin about revoked site due to SSL requirements.', __METHOD__, 'info' ); |
|
205 | 205 | |
206 | 206 | return true; |
207 | 207 | } |
208 | 208 | |
209 | 209 | $body = [ |
210 | - 'publicKey' => $this->config->get_setting('auth/api_key'), |
|
210 | + 'publicKey' => $this->config->get_setting( 'auth/api_key' ), |
|
211 | 211 | ]; |
212 | 212 | |
213 | - $api_response = $remote->send('sites/'.$secret_id, $body, 'DELETE'); |
|
213 | + $api_response = $remote->send( 'sites/' . $secret_id, $body, 'DELETE' ); |
|
214 | 214 | |
215 | - if (is_wp_error($api_response)) { |
|
215 | + if ( is_wp_error( $api_response ) ) { |
|
216 | 216 | return $api_response; |
217 | 217 | } |
218 | 218 | |
219 | - $response = $remote->handle_response($api_response); |
|
219 | + $response = $remote->handle_response( $api_response ); |
|
220 | 220 | |
221 | - if (is_wp_error($response)) { |
|
221 | + if ( is_wp_error( $response ) ) { |
|
222 | 222 | return $response; |
223 | 223 | } |
224 | 224 |
@@ -14,8 +14,7 @@ discard block |
||
14 | 14 | |
15 | 15 | use WP_Error; |
16 | 16 | |
17 | -class SiteAccess |
|
18 | -{ |
|
17 | +class SiteAccess { |
|
19 | 18 | /** |
20 | 19 | * @var Config |
21 | 20 | */ |
@@ -34,8 +33,7 @@ discard block |
||
34 | 33 | 'extend', |
35 | 34 | ]; |
36 | 35 | |
37 | - public function __construct(Config $config, Logging $logging) |
|
38 | - { |
|
36 | + public function __construct(Config $config, Logging $logging) { |
|
39 | 37 | $this->config = $config; |
40 | 38 | $this->logging = $logging; |
41 | 39 | } |
@@ -49,8 +47,7 @@ discard block |
||
49 | 47 | * |
50 | 48 | * @return true|WP_Error True if successfully created secret on TrustedLogin servers; WP_Error if failed. |
51 | 49 | */ |
52 | - public function sync_secret($secret_id, $site_identifier_hash, $action = 'create') |
|
53 | - { |
|
50 | + public function sync_secret($secret_id, $site_identifier_hash, $action = 'create') { |
|
54 | 51 | $logging = new Logging($this->config); |
55 | 52 | $remote = new Remote($this->config, $logging); |
56 | 53 | $encryption = new Encryption($this->config, $remote, $logging); |
@@ -111,8 +108,7 @@ discard block |
||
111 | 108 | * |
112 | 109 | * @return string|null $access_key, if exists. Either a hashed license key or a generated hash. If error occurs, returns null. |
113 | 110 | */ |
114 | - public function get_access_key() |
|
115 | - { |
|
111 | + public function get_access_key() { |
|
116 | 112 | |
117 | 113 | // If there's a license, return a hash of the license. |
118 | 114 | $license_key = $this->get_license_key(true); |
@@ -139,8 +135,7 @@ discard block |
||
139 | 135 | * |
140 | 136 | * @return string|null|WP_Error License key (hashed if $hashed is true) or null if not found. Returns WP_Error if error occurs. |
141 | 137 | */ |
142 | - public function get_license_key($hashed = false) |
|
143 | - { |
|
138 | + public function get_license_key($hashed = false) { |
|
144 | 139 | |
145 | 140 | // If no license key is provided |
146 | 141 | $license_key_config = $this->config->get_setting('auth/license_key', null); |
@@ -179,8 +174,7 @@ discard block |
||
179 | 174 | * |
180 | 175 | * @return string|WP_Error Access Key prepended with TL, or something went wrong. |
181 | 176 | */ |
182 | - private function generate_access_key() |
|
183 | - { |
|
177 | + private function generate_access_key() { |
|
184 | 178 | $hash = Encryption::hash(get_current_blog_id().get_site_url().$this->config->get_setting('auth/api_key'), 32); |
185 | 179 | |
186 | 180 | if (is_wp_error($hash)) { |
@@ -198,8 +192,7 @@ discard block |
||
198 | 192 | * |
199 | 193 | * @return true|\WP_Error Was the sync to TrustedLogin successful |
200 | 194 | */ |
201 | - public function revoke($secret_id, Remote $remote) |
|
202 | - { |
|
195 | + public function revoke($secret_id, Remote $remote) { |
|
203 | 196 | if (!$this->config->meets_ssl_requirement()) { |
204 | 197 | $this->logging->log('Not notifying TrustedLogin about revoked site due to SSL requirements.', __METHOD__, 'info'); |
205 | 198 |
@@ -11,88 +11,88 @@ |
||
11 | 11 | |
12 | 12 | // Exit if accessed directly |
13 | 13 | if (!defined('ABSPATH')) { |
14 | - exit; |
|
14 | + exit; |
|
15 | 15 | } |
16 | 16 | |
17 | 17 | final class Ajax |
18 | 18 | { |
19 | - /** |
|
20 | - * @var \GravityView\TrustedLogin\Config |
|
21 | - */ |
|
22 | - private $config; |
|
23 | - |
|
24 | - /** |
|
25 | - * @var null|\TrustedLogin\Logging |
|
26 | - */ |
|
27 | - private $logging; |
|
28 | - |
|
29 | - /** |
|
30 | - * Cron constructor. |
|
31 | - * |
|
32 | - * @param Config $config |
|
33 | - * @param Logging|null $logging |
|
34 | - */ |
|
35 | - public function __construct(Config $config, Logging $logging) |
|
36 | - { |
|
37 | - $this->config = $config; |
|
38 | - $this->logging = $logging; |
|
39 | - } |
|
40 | - |
|
41 | - public function init() |
|
42 | - { |
|
43 | - add_action('wp_ajax_tl_'.$this->config->ns().'_gen_support', [$this, 'ajax_generate_support']); |
|
44 | - } |
|
45 | - |
|
46 | - /** |
|
47 | - * AJAX handler for maybe generating a Support User. |
|
48 | - * |
|
49 | - * @since 1.0.0 |
|
50 | - * |
|
51 | - * @return void Sends a JSON success or error message based on what happens |
|
52 | - */ |
|
53 | - public function ajax_generate_support() |
|
54 | - { |
|
55 | - if (empty($_POST['vendor'])) { |
|
56 | - $this->logging->log('Vendor not defined in TrustedLogin configuration.', __METHOD__, 'critical'); |
|
57 | - |
|
58 | - wp_send_json_error(['message' => 'Vendor not defined in TrustedLogin configuration.']); |
|
59 | - } |
|
60 | - |
|
61 | - // There are multiple TrustedLogin instances, and this is not the one being called. |
|
62 | - // This should not occur, since the AJAX action is namespaced. |
|
63 | - if ($this->config->ns() !== $_POST['vendor']) { |
|
64 | - $this->logging->log('Vendor does not match TrustedLogin configuration.', __METHOD__, 'critical'); |
|
65 | - |
|
66 | - wp_send_json_error(['message' => 'Vendor does not match.']); |
|
67 | - |
|
68 | - return; |
|
69 | - } |
|
70 | - |
|
71 | - if (empty($_POST['_nonce'])) { |
|
72 | - wp_send_json_error(['message' => 'Nonce not sent in the request.']); |
|
73 | - } |
|
74 | - |
|
75 | - if (!check_ajax_referer('tl_nonce-'.get_current_user_id(), '_nonce', false)) { |
|
76 | - wp_send_json_error(['message' => 'Verification issue: Request could not be verified. Please reload the page.']); |
|
77 | - } |
|
78 | - |
|
79 | - if (!current_user_can('create_users')) { |
|
80 | - $this->logging->log('Current user does not have `create_users` capability when trying to grant access.', __METHOD__, 'error'); |
|
81 | - |
|
82 | - wp_send_json_error(['message' => 'You do not have the ability to create users.']); |
|
83 | - } |
|
84 | - |
|
85 | - $client = new Client($this->config, false); |
|
86 | - |
|
87 | - $response = $client->grant_access(); |
|
88 | - |
|
89 | - if (is_wp_error($response)) { |
|
90 | - $error_data = $response->get_error_data(); |
|
91 | - $error_code = isset($error_data['error_code']) ? $error_data['error_code'] : 500; |
|
92 | - |
|
93 | - wp_send_json_error(['message' => $response->get_error_message()], $error_code); |
|
94 | - } |
|
95 | - |
|
96 | - wp_send_json_success($response, 201); |
|
97 | - } |
|
19 | + /** |
|
20 | + * @var \GravityView\TrustedLogin\Config |
|
21 | + */ |
|
22 | + private $config; |
|
23 | + |
|
24 | + /** |
|
25 | + * @var null|\TrustedLogin\Logging |
|
26 | + */ |
|
27 | + private $logging; |
|
28 | + |
|
29 | + /** |
|
30 | + * Cron constructor. |
|
31 | + * |
|
32 | + * @param Config $config |
|
33 | + * @param Logging|null $logging |
|
34 | + */ |
|
35 | + public function __construct(Config $config, Logging $logging) |
|
36 | + { |
|
37 | + $this->config = $config; |
|
38 | + $this->logging = $logging; |
|
39 | + } |
|
40 | + |
|
41 | + public function init() |
|
42 | + { |
|
43 | + add_action('wp_ajax_tl_'.$this->config->ns().'_gen_support', [$this, 'ajax_generate_support']); |
|
44 | + } |
|
45 | + |
|
46 | + /** |
|
47 | + * AJAX handler for maybe generating a Support User. |
|
48 | + * |
|
49 | + * @since 1.0.0 |
|
50 | + * |
|
51 | + * @return void Sends a JSON success or error message based on what happens |
|
52 | + */ |
|
53 | + public function ajax_generate_support() |
|
54 | + { |
|
55 | + if (empty($_POST['vendor'])) { |
|
56 | + $this->logging->log('Vendor not defined in TrustedLogin configuration.', __METHOD__, 'critical'); |
|
57 | + |
|
58 | + wp_send_json_error(['message' => 'Vendor not defined in TrustedLogin configuration.']); |
|
59 | + } |
|
60 | + |
|
61 | + // There are multiple TrustedLogin instances, and this is not the one being called. |
|
62 | + // This should not occur, since the AJAX action is namespaced. |
|
63 | + if ($this->config->ns() !== $_POST['vendor']) { |
|
64 | + $this->logging->log('Vendor does not match TrustedLogin configuration.', __METHOD__, 'critical'); |
|
65 | + |
|
66 | + wp_send_json_error(['message' => 'Vendor does not match.']); |
|
67 | + |
|
68 | + return; |
|
69 | + } |
|
70 | + |
|
71 | + if (empty($_POST['_nonce'])) { |
|
72 | + wp_send_json_error(['message' => 'Nonce not sent in the request.']); |
|
73 | + } |
|
74 | + |
|
75 | + if (!check_ajax_referer('tl_nonce-'.get_current_user_id(), '_nonce', false)) { |
|
76 | + wp_send_json_error(['message' => 'Verification issue: Request could not be verified. Please reload the page.']); |
|
77 | + } |
|
78 | + |
|
79 | + if (!current_user_can('create_users')) { |
|
80 | + $this->logging->log('Current user does not have `create_users` capability when trying to grant access.', __METHOD__, 'error'); |
|
81 | + |
|
82 | + wp_send_json_error(['message' => 'You do not have the ability to create users.']); |
|
83 | + } |
|
84 | + |
|
85 | + $client = new Client($this->config, false); |
|
86 | + |
|
87 | + $response = $client->grant_access(); |
|
88 | + |
|
89 | + if (is_wp_error($response)) { |
|
90 | + $error_data = $response->get_error_data(); |
|
91 | + $error_code = isset($error_data['error_code']) ? $error_data['error_code'] : 500; |
|
92 | + |
|
93 | + wp_send_json_error(['message' => $response->get_error_message()], $error_code); |
|
94 | + } |
|
95 | + |
|
96 | + wp_send_json_success($response, 201); |
|
97 | + } |
|
98 | 98 | } |
@@ -10,7 +10,7 @@ discard block |
||
10 | 10 | namespace GravityView\TrustedLogin; |
11 | 11 | |
12 | 12 | // Exit if accessed directly |
13 | -if (!defined('ABSPATH')) { |
|
13 | +if ( ! defined( 'ABSPATH' ) ) { |
|
14 | 14 | exit; |
15 | 15 | } |
16 | 16 | |
@@ -32,7 +32,7 @@ discard block |
||
32 | 32 | * @param Config $config |
33 | 33 | * @param Logging|null $logging |
34 | 34 | */ |
35 | - public function __construct(Config $config, Logging $logging) |
|
35 | + public function __construct( Config $config, Logging $logging ) |
|
36 | 36 | { |
37 | 37 | $this->config = $config; |
38 | 38 | $this->logging = $logging; |
@@ -40,7 +40,7 @@ discard block |
||
40 | 40 | |
41 | 41 | public function init() |
42 | 42 | { |
43 | - add_action('wp_ajax_tl_'.$this->config->ns().'_gen_support', [$this, 'ajax_generate_support']); |
|
43 | + add_action( 'wp_ajax_tl_' . $this->config->ns() . '_gen_support', [ $this, 'ajax_generate_support' ] ); |
|
44 | 44 | } |
45 | 45 | |
46 | 46 | /** |
@@ -52,47 +52,47 @@ discard block |
||
52 | 52 | */ |
53 | 53 | public function ajax_generate_support() |
54 | 54 | { |
55 | - if (empty($_POST['vendor'])) { |
|
56 | - $this->logging->log('Vendor not defined in TrustedLogin configuration.', __METHOD__, 'critical'); |
|
55 | + if ( empty( $_POST[ 'vendor' ] ) ) { |
|
56 | + $this->logging->log( 'Vendor not defined in TrustedLogin configuration.', __METHOD__, 'critical' ); |
|
57 | 57 | |
58 | - wp_send_json_error(['message' => 'Vendor not defined in TrustedLogin configuration.']); |
|
58 | + wp_send_json_error( [ 'message' => 'Vendor not defined in TrustedLogin configuration.' ] ); |
|
59 | 59 | } |
60 | 60 | |
61 | 61 | // There are multiple TrustedLogin instances, and this is not the one being called. |
62 | 62 | // This should not occur, since the AJAX action is namespaced. |
63 | - if ($this->config->ns() !== $_POST['vendor']) { |
|
64 | - $this->logging->log('Vendor does not match TrustedLogin configuration.', __METHOD__, 'critical'); |
|
63 | + if ( $this->config->ns() !== $_POST[ 'vendor' ] ) { |
|
64 | + $this->logging->log( 'Vendor does not match TrustedLogin configuration.', __METHOD__, 'critical' ); |
|
65 | 65 | |
66 | - wp_send_json_error(['message' => 'Vendor does not match.']); |
|
66 | + wp_send_json_error( [ 'message' => 'Vendor does not match.' ] ); |
|
67 | 67 | |
68 | 68 | return; |
69 | 69 | } |
70 | 70 | |
71 | - if (empty($_POST['_nonce'])) { |
|
72 | - wp_send_json_error(['message' => 'Nonce not sent in the request.']); |
|
71 | + if ( empty( $_POST[ '_nonce' ] ) ) { |
|
72 | + wp_send_json_error( [ 'message' => 'Nonce not sent in the request.' ] ); |
|
73 | 73 | } |
74 | 74 | |
75 | - if (!check_ajax_referer('tl_nonce-'.get_current_user_id(), '_nonce', false)) { |
|
76 | - wp_send_json_error(['message' => 'Verification issue: Request could not be verified. Please reload the page.']); |
|
75 | + if ( ! check_ajax_referer( 'tl_nonce-' . get_current_user_id(), '_nonce', false ) ) { |
|
76 | + wp_send_json_error( [ 'message' => 'Verification issue: Request could not be verified. Please reload the page.' ] ); |
|
77 | 77 | } |
78 | 78 | |
79 | - if (!current_user_can('create_users')) { |
|
80 | - $this->logging->log('Current user does not have `create_users` capability when trying to grant access.', __METHOD__, 'error'); |
|
79 | + if ( ! current_user_can( 'create_users' ) ) { |
|
80 | + $this->logging->log( 'Current user does not have `create_users` capability when trying to grant access.', __METHOD__, 'error' ); |
|
81 | 81 | |
82 | - wp_send_json_error(['message' => 'You do not have the ability to create users.']); |
|
82 | + wp_send_json_error( [ 'message' => 'You do not have the ability to create users.' ] ); |
|
83 | 83 | } |
84 | 84 | |
85 | - $client = new Client($this->config, false); |
|
85 | + $client = new Client( $this->config, false ); |
|
86 | 86 | |
87 | 87 | $response = $client->grant_access(); |
88 | 88 | |
89 | - if (is_wp_error($response)) { |
|
89 | + if ( is_wp_error( $response ) ) { |
|
90 | 90 | $error_data = $response->get_error_data(); |
91 | - $error_code = isset($error_data['error_code']) ? $error_data['error_code'] : 500; |
|
91 | + $error_code = isset( $error_data[ 'error_code' ] ) ? $error_data[ 'error_code' ] : 500; |
|
92 | 92 | |
93 | - wp_send_json_error(['message' => $response->get_error_message()], $error_code); |
|
93 | + wp_send_json_error( [ 'message' => $response->get_error_message() ], $error_code ); |
|
94 | 94 | } |
95 | 95 | |
96 | - wp_send_json_success($response, 201); |
|
96 | + wp_send_json_success( $response, 201 ); |
|
97 | 97 | } |
98 | 98 | } |
@@ -14,8 +14,7 @@ discard block |
||
14 | 14 | exit; |
15 | 15 | } |
16 | 16 | |
17 | -final class Ajax |
|
18 | -{ |
|
17 | +final class Ajax { |
|
19 | 18 | /** |
20 | 19 | * @var \GravityView\TrustedLogin\Config |
21 | 20 | */ |
@@ -32,14 +31,12 @@ discard block |
||
32 | 31 | * @param Config $config |
33 | 32 | * @param Logging|null $logging |
34 | 33 | */ |
35 | - public function __construct(Config $config, Logging $logging) |
|
36 | - { |
|
34 | + public function __construct(Config $config, Logging $logging) { |
|
37 | 35 | $this->config = $config; |
38 | 36 | $this->logging = $logging; |
39 | 37 | } |
40 | 38 | |
41 | - public function init() |
|
42 | - { |
|
39 | + public function init() { |
|
43 | 40 | add_action('wp_ajax_tl_'.$this->config->ns().'_gen_support', [$this, 'ajax_generate_support']); |
44 | 41 | } |
45 | 42 | |
@@ -50,8 +47,7 @@ discard block |
||
50 | 47 | * |
51 | 48 | * @return void Sends a JSON success or error message based on what happens |
52 | 49 | */ |
53 | - public function ajax_generate_support() |
|
54 | - { |
|
50 | + public function ajax_generate_support() { |
|
55 | 51 | if (empty($_POST['vendor'])) { |
56 | 52 | $this->logging->log('Vendor not defined in TrustedLogin configuration.', __METHOD__, 'critical'); |
57 | 53 |
@@ -11,106 +11,106 @@ |
||
11 | 11 | |
12 | 12 | // Exit if accessed directly |
13 | 13 | if (!defined('ABSPATH')) { |
14 | - exit; |
|
14 | + exit; |
|
15 | 15 | } |
16 | 16 | |
17 | 17 | final class Cron |
18 | 18 | { |
19 | - /** |
|
20 | - * @var \GravityView\TrustedLogin\Config |
|
21 | - */ |
|
22 | - private $config; |
|
23 | - |
|
24 | - /** |
|
25 | - * @var string |
|
26 | - */ |
|
27 | - private $hook_name; |
|
28 | - |
|
29 | - /** |
|
30 | - * @var null|\TrustedLogin\Logging |
|
31 | - */ |
|
32 | - private $logging; |
|
33 | - |
|
34 | - /** |
|
35 | - * Cron constructor. |
|
36 | - * |
|
37 | - * @param Config $config |
|
38 | - * @param Logging|null $logging |
|
39 | - */ |
|
40 | - public function __construct(Config $config, Logging $logging) |
|
41 | - { |
|
42 | - $this->config = $config; |
|
43 | - $this->logging = $logging; |
|
44 | - |
|
45 | - $this->hook_name = 'trustedlogin/'.$this->config->ns().'/access/revoke'; |
|
46 | - } |
|
47 | - |
|
48 | - public function init() |
|
49 | - { |
|
50 | - add_action($this->hook_name, [$this, 'revoke'], 1); |
|
51 | - } |
|
52 | - |
|
53 | - /** |
|
54 | - * @param int $expiration_timestamp |
|
55 | - * @param string $identifier_hash |
|
56 | - * |
|
57 | - * @return bool |
|
58 | - */ |
|
59 | - public function schedule($expiration_timestamp, $identifier_hash) |
|
60 | - { |
|
61 | - $hash = Encryption::hash($identifier_hash); |
|
62 | - |
|
63 | - if (is_wp_error($hash)) { |
|
64 | - $this->logging->log($hash, __METHOD__); |
|
65 | - |
|
66 | - return false; |
|
67 | - } |
|
68 | - |
|
69 | - $args = [$hash]; |
|
70 | - |
|
71 | - $scheduled_expiration = wp_schedule_single_event($expiration_timestamp, $this->hook_name, $args); |
|
72 | - |
|
73 | - $this->logging->log('Scheduled Expiration: '.var_export($scheduled_expiration, true).'; identifier: '.$identifier_hash, __METHOD__, 'info'); |
|
74 | - |
|
75 | - return $scheduled_expiration; |
|
76 | - } |
|
77 | - |
|
78 | - /** |
|
79 | - * @param int $expiration_timestamp |
|
80 | - * @param string $site_identifier_hash |
|
81 | - * |
|
82 | - * @return bool |
|
83 | - */ |
|
84 | - public function reschedule($expiration_timestamp, $site_identifier_hash) |
|
85 | - { |
|
86 | - $unschedule_expiration = wp_clear_scheduled_hook($this->hook_name, [$site_identifier_hash]); |
|
87 | - |
|
88 | - if (false === $unschedule_expiration) { |
|
89 | - $this->logging->log(sprintf('Could not unschedule event for %s', $this->hook_name), __METHOD__, 'error'); |
|
90 | - |
|
91 | - return false; |
|
92 | - } |
|
93 | - |
|
94 | - return $this->schedule($expiration_timestamp, $site_identifier_hash); |
|
95 | - } |
|
96 | - |
|
97 | - /** |
|
98 | - * Hooked Action: Revokes access for a specific support user. |
|
99 | - * |
|
100 | - * @since 1.0.0 |
|
101 | - * |
|
102 | - * @param string $identifier_hash Identifier hash for the user associated with the cron job |
|
103 | - * |
|
104 | - * @todo |
|
105 | - * |
|
106 | - * @return void |
|
107 | - */ |
|
108 | - public function revoke($identifier_hash) |
|
109 | - { |
|
110 | - $this->logging->log('Running cron job to disable user. ID: '.$identifier_hash, __METHOD__, 'notice'); |
|
111 | - |
|
112 | - $Client = new Client($this->config, false); |
|
113 | - |
|
114 | - $Client->revoke_access($identifier_hash); |
|
115 | - } |
|
19 | + /** |
|
20 | + * @var \GravityView\TrustedLogin\Config |
|
21 | + */ |
|
22 | + private $config; |
|
23 | + |
|
24 | + /** |
|
25 | + * @var string |
|
26 | + */ |
|
27 | + private $hook_name; |
|
28 | + |
|
29 | + /** |
|
30 | + * @var null|\TrustedLogin\Logging |
|
31 | + */ |
|
32 | + private $logging; |
|
33 | + |
|
34 | + /** |
|
35 | + * Cron constructor. |
|
36 | + * |
|
37 | + * @param Config $config |
|
38 | + * @param Logging|null $logging |
|
39 | + */ |
|
40 | + public function __construct(Config $config, Logging $logging) |
|
41 | + { |
|
42 | + $this->config = $config; |
|
43 | + $this->logging = $logging; |
|
44 | + |
|
45 | + $this->hook_name = 'trustedlogin/'.$this->config->ns().'/access/revoke'; |
|
46 | + } |
|
47 | + |
|
48 | + public function init() |
|
49 | + { |
|
50 | + add_action($this->hook_name, [$this, 'revoke'], 1); |
|
51 | + } |
|
52 | + |
|
53 | + /** |
|
54 | + * @param int $expiration_timestamp |
|
55 | + * @param string $identifier_hash |
|
56 | + * |
|
57 | + * @return bool |
|
58 | + */ |
|
59 | + public function schedule($expiration_timestamp, $identifier_hash) |
|
60 | + { |
|
61 | + $hash = Encryption::hash($identifier_hash); |
|
62 | + |
|
63 | + if (is_wp_error($hash)) { |
|
64 | + $this->logging->log($hash, __METHOD__); |
|
65 | + |
|
66 | + return false; |
|
67 | + } |
|
68 | + |
|
69 | + $args = [$hash]; |
|
70 | + |
|
71 | + $scheduled_expiration = wp_schedule_single_event($expiration_timestamp, $this->hook_name, $args); |
|
72 | + |
|
73 | + $this->logging->log('Scheduled Expiration: '.var_export($scheduled_expiration, true).'; identifier: '.$identifier_hash, __METHOD__, 'info'); |
|
74 | + |
|
75 | + return $scheduled_expiration; |
|
76 | + } |
|
77 | + |
|
78 | + /** |
|
79 | + * @param int $expiration_timestamp |
|
80 | + * @param string $site_identifier_hash |
|
81 | + * |
|
82 | + * @return bool |
|
83 | + */ |
|
84 | + public function reschedule($expiration_timestamp, $site_identifier_hash) |
|
85 | + { |
|
86 | + $unschedule_expiration = wp_clear_scheduled_hook($this->hook_name, [$site_identifier_hash]); |
|
87 | + |
|
88 | + if (false === $unschedule_expiration) { |
|
89 | + $this->logging->log(sprintf('Could not unschedule event for %s', $this->hook_name), __METHOD__, 'error'); |
|
90 | + |
|
91 | + return false; |
|
92 | + } |
|
93 | + |
|
94 | + return $this->schedule($expiration_timestamp, $site_identifier_hash); |
|
95 | + } |
|
96 | + |
|
97 | + /** |
|
98 | + * Hooked Action: Revokes access for a specific support user. |
|
99 | + * |
|
100 | + * @since 1.0.0 |
|
101 | + * |
|
102 | + * @param string $identifier_hash Identifier hash for the user associated with the cron job |
|
103 | + * |
|
104 | + * @todo |
|
105 | + * |
|
106 | + * @return void |
|
107 | + */ |
|
108 | + public function revoke($identifier_hash) |
|
109 | + { |
|
110 | + $this->logging->log('Running cron job to disable user. ID: '.$identifier_hash, __METHOD__, 'notice'); |
|
111 | + |
|
112 | + $Client = new Client($this->config, false); |
|
113 | + |
|
114 | + $Client->revoke_access($identifier_hash); |
|
115 | + } |
|
116 | 116 | } |
@@ -10,7 +10,7 @@ discard block |
||
10 | 10 | namespace GravityView\TrustedLogin; |
11 | 11 | |
12 | 12 | // Exit if accessed directly |
13 | -if (!defined('ABSPATH')) { |
|
13 | +if ( ! defined( 'ABSPATH' ) ) { |
|
14 | 14 | exit; |
15 | 15 | } |
16 | 16 | |
@@ -37,17 +37,17 @@ discard block |
||
37 | 37 | * @param Config $config |
38 | 38 | * @param Logging|null $logging |
39 | 39 | */ |
40 | - public function __construct(Config $config, Logging $logging) |
|
40 | + public function __construct( Config $config, Logging $logging ) |
|
41 | 41 | { |
42 | 42 | $this->config = $config; |
43 | 43 | $this->logging = $logging; |
44 | 44 | |
45 | - $this->hook_name = 'trustedlogin/'.$this->config->ns().'/access/revoke'; |
|
45 | + $this->hook_name = 'trustedlogin/' . $this->config->ns() . '/access/revoke'; |
|
46 | 46 | } |
47 | 47 | |
48 | 48 | public function init() |
49 | 49 | { |
50 | - add_action($this->hook_name, [$this, 'revoke'], 1); |
|
50 | + add_action( $this->hook_name, [ $this, 'revoke' ], 1 ); |
|
51 | 51 | } |
52 | 52 | |
53 | 53 | /** |
@@ -56,21 +56,21 @@ discard block |
||
56 | 56 | * |
57 | 57 | * @return bool |
58 | 58 | */ |
59 | - public function schedule($expiration_timestamp, $identifier_hash) |
|
59 | + public function schedule( $expiration_timestamp, $identifier_hash ) |
|
60 | 60 | { |
61 | - $hash = Encryption::hash($identifier_hash); |
|
61 | + $hash = Encryption::hash( $identifier_hash ); |
|
62 | 62 | |
63 | - if (is_wp_error($hash)) { |
|
64 | - $this->logging->log($hash, __METHOD__); |
|
63 | + if ( is_wp_error( $hash ) ) { |
|
64 | + $this->logging->log( $hash, __METHOD__ ); |
|
65 | 65 | |
66 | 66 | return false; |
67 | 67 | } |
68 | 68 | |
69 | - $args = [$hash]; |
|
69 | + $args = [ $hash ]; |
|
70 | 70 | |
71 | - $scheduled_expiration = wp_schedule_single_event($expiration_timestamp, $this->hook_name, $args); |
|
71 | + $scheduled_expiration = wp_schedule_single_event( $expiration_timestamp, $this->hook_name, $args ); |
|
72 | 72 | |
73 | - $this->logging->log('Scheduled Expiration: '.var_export($scheduled_expiration, true).'; identifier: '.$identifier_hash, __METHOD__, 'info'); |
|
73 | + $this->logging->log( 'Scheduled Expiration: ' . var_export( $scheduled_expiration, true ) . '; identifier: ' . $identifier_hash, __METHOD__, 'info' ); |
|
74 | 74 | |
75 | 75 | return $scheduled_expiration; |
76 | 76 | } |
@@ -81,17 +81,17 @@ discard block |
||
81 | 81 | * |
82 | 82 | * @return bool |
83 | 83 | */ |
84 | - public function reschedule($expiration_timestamp, $site_identifier_hash) |
|
84 | + public function reschedule( $expiration_timestamp, $site_identifier_hash ) |
|
85 | 85 | { |
86 | - $unschedule_expiration = wp_clear_scheduled_hook($this->hook_name, [$site_identifier_hash]); |
|
86 | + $unschedule_expiration = wp_clear_scheduled_hook( $this->hook_name, [ $site_identifier_hash ] ); |
|
87 | 87 | |
88 | - if (false === $unschedule_expiration) { |
|
89 | - $this->logging->log(sprintf('Could not unschedule event for %s', $this->hook_name), __METHOD__, 'error'); |
|
88 | + if ( false === $unschedule_expiration ) { |
|
89 | + $this->logging->log( sprintf( 'Could not unschedule event for %s', $this->hook_name ), __METHOD__, 'error' ); |
|
90 | 90 | |
91 | 91 | return false; |
92 | 92 | } |
93 | 93 | |
94 | - return $this->schedule($expiration_timestamp, $site_identifier_hash); |
|
94 | + return $this->schedule( $expiration_timestamp, $site_identifier_hash ); |
|
95 | 95 | } |
96 | 96 | |
97 | 97 | /** |
@@ -105,12 +105,12 @@ discard block |
||
105 | 105 | * |
106 | 106 | * @return void |
107 | 107 | */ |
108 | - public function revoke($identifier_hash) |
|
108 | + public function revoke( $identifier_hash ) |
|
109 | 109 | { |
110 | - $this->logging->log('Running cron job to disable user. ID: '.$identifier_hash, __METHOD__, 'notice'); |
|
110 | + $this->logging->log( 'Running cron job to disable user. ID: ' . $identifier_hash, __METHOD__, 'notice' ); |
|
111 | 111 | |
112 | - $Client = new Client($this->config, false); |
|
112 | + $Client = new Client( $this->config, false ); |
|
113 | 113 | |
114 | - $Client->revoke_access($identifier_hash); |
|
114 | + $Client->revoke_access( $identifier_hash ); |
|
115 | 115 | } |
116 | 116 | } |
@@ -14,8 +14,7 @@ discard block |
||
14 | 14 | exit; |
15 | 15 | } |
16 | 16 | |
17 | -final class Cron |
|
18 | -{ |
|
17 | +final class Cron { |
|
19 | 18 | /** |
20 | 19 | * @var \GravityView\TrustedLogin\Config |
21 | 20 | */ |
@@ -37,16 +36,14 @@ discard block |
||
37 | 36 | * @param Config $config |
38 | 37 | * @param Logging|null $logging |
39 | 38 | */ |
40 | - public function __construct(Config $config, Logging $logging) |
|
41 | - { |
|
39 | + public function __construct(Config $config, Logging $logging) { |
|
42 | 40 | $this->config = $config; |
43 | 41 | $this->logging = $logging; |
44 | 42 | |
45 | 43 | $this->hook_name = 'trustedlogin/'.$this->config->ns().'/access/revoke'; |
46 | 44 | } |
47 | 45 | |
48 | - public function init() |
|
49 | - { |
|
46 | + public function init() { |
|
50 | 47 | add_action($this->hook_name, [$this, 'revoke'], 1); |
51 | 48 | } |
52 | 49 | |
@@ -56,8 +53,7 @@ discard block |
||
56 | 53 | * |
57 | 54 | * @return bool |
58 | 55 | */ |
59 | - public function schedule($expiration_timestamp, $identifier_hash) |
|
60 | - { |
|
56 | + public function schedule($expiration_timestamp, $identifier_hash) { |
|
61 | 57 | $hash = Encryption::hash($identifier_hash); |
62 | 58 | |
63 | 59 | if (is_wp_error($hash)) { |
@@ -81,8 +77,7 @@ discard block |
||
81 | 77 | * |
82 | 78 | * @return bool |
83 | 79 | */ |
84 | - public function reschedule($expiration_timestamp, $site_identifier_hash) |
|
85 | - { |
|
80 | + public function reschedule($expiration_timestamp, $site_identifier_hash) { |
|
86 | 81 | $unschedule_expiration = wp_clear_scheduled_hook($this->hook_name, [$site_identifier_hash]); |
87 | 82 | |
88 | 83 | if (false === $unschedule_expiration) { |
@@ -105,8 +100,7 @@ discard block |
||
105 | 100 | * |
106 | 101 | * @return void |
107 | 102 | */ |
108 | - public function revoke($identifier_hash) |
|
109 | - { |
|
103 | + public function revoke($identifier_hash) { |
|
110 | 104 | $this->logging->log('Running cron job to disable user. ID: '.$identifier_hash, __METHOD__, 'notice'); |
111 | 105 | |
112 | 106 | $Client = new Client($this->config, false); |
@@ -16,308 +16,308 @@ |
||
16 | 16 | |
17 | 17 | class Logging |
18 | 18 | { |
19 | - /** |
|
20 | - * Path to logging directory (inside the WP Uploads base dir). |
|
21 | - */ |
|
22 | - const DIRECTORY_PATH = 'trustedlogin-logs/'; |
|
23 | - |
|
24 | - /** |
|
25 | - * @var string Namespace for the vendor |
|
26 | - */ |
|
27 | - private $ns; |
|
28 | - |
|
29 | - /** |
|
30 | - * @var bool |
|
31 | - */ |
|
32 | - private $logging_enabled = false; |
|
33 | - |
|
34 | - /** |
|
35 | - * @var Logger|null|false Null: not instantiated; False: failed to instantiate. |
|
36 | - */ |
|
37 | - private $klogger = null; |
|
38 | - |
|
39 | - /** |
|
40 | - * Logger constructor. |
|
41 | - */ |
|
42 | - public function __construct(Config $config) |
|
43 | - { |
|
44 | - $this->ns = $config->ns(); |
|
45 | - |
|
46 | - $this->logging_enabled = $config->get_setting('logging/enabled', false); |
|
47 | - |
|
48 | - $this->klogger = $this->setup_klogger($config); |
|
49 | - } |
|
50 | - |
|
51 | - /** |
|
52 | - * Attempts to initialize KLogger logging. |
|
53 | - * |
|
54 | - * @param Config $config |
|
55 | - * |
|
56 | - * @return false|Logger |
|
57 | - */ |
|
58 | - private function setup_klogger($config) |
|
59 | - { |
|
60 | - if (!class_exists('GravityView\Katzgrau\KLogger\Logger')) { |
|
61 | - $this->log('KLogger not found.', __METHOD__, 'error'); |
|
62 | - |
|
63 | - return false; |
|
64 | - } |
|
65 | - |
|
66 | - $logging_directory = null; |
|
67 | - |
|
68 | - $configured_logging_dir = $config->get_setting('logging/directory', ''); |
|
69 | - |
|
70 | - if (!empty($configured_logging_dir)) { |
|
71 | - $logging_directory = $this->check_directory($configured_logging_dir); |
|
72 | - |
|
73 | - if (!$logging_directory) { |
|
74 | - return false; |
|
75 | - } |
|
76 | - } |
|
77 | - |
|
78 | - if (!$logging_directory) { |
|
79 | - $logging_directory = $this->maybe_make_logging_directory(); |
|
80 | - } |
|
81 | - |
|
82 | - // Directory cannot be found or created. Cannot log. |
|
83 | - if (!$logging_directory) { |
|
84 | - return false; |
|
85 | - } |
|
86 | - |
|
87 | - // Directory cannot be written to |
|
88 | - if (!$this->check_directory($logging_directory)) { |
|
89 | - return false; |
|
90 | - } |
|
91 | - |
|
92 | - try { |
|
93 | - $DateTime = new \DateTime('@'.time()); |
|
94 | - |
|
95 | - // Filename hash changes every day, make it harder to guess |
|
96 | - $filename_hash_data = $this->ns.home_url('/').$DateTime->format('z'); |
|
97 | - |
|
98 | - $default_options = [ |
|
99 | - 'extension' => 'log', |
|
100 | - 'dateFormat' => 'Y-m-d G:i:s.u', |
|
101 | - 'filename' => sprintf('trustedlogin-client-debug-%s-%s', $DateTime->format('Y-m-d'), wp_hash($filename_hash_data)), |
|
102 | - 'flushFrequency' => false, |
|
103 | - 'logFormat' => false, |
|
104 | - 'appendContext' => true, |
|
105 | - ]; |
|
106 | - |
|
107 | - $settings_options = $config->get_setting('logging/options', $default_options); |
|
108 | - |
|
109 | - $options = wp_parse_args($settings_options, $default_options); |
|
110 | - |
|
111 | - $klogger = new Logger( |
|
112 | - $logging_directory, |
|
113 | - $config->get_setting('logging/threshold', 'notice'), |
|
114 | - $options |
|
115 | - ); |
|
116 | - } catch (\RuntimeException $exception) { |
|
117 | - $this->log('Could not initialize KLogger: '.$exception->getMessage(), __METHOD__, 'error'); |
|
118 | - |
|
119 | - return false; |
|
120 | - } catch (\Exception $exception) { |
|
121 | - $this->log('DateTime could not be created: '.$exception->getMessage(), __METHOD__, 'error'); |
|
122 | - |
|
123 | - return false; |
|
124 | - } |
|
125 | - |
|
126 | - return $klogger; |
|
127 | - } |
|
128 | - |
|
129 | - /** |
|
130 | - * Checks whether a path exists and is writable. |
|
131 | - * |
|
132 | - * @param string $dirpath Path to directory |
|
133 | - * |
|
134 | - * @return bool|string If exists and writable, returns original string. Otherwise, returns false. |
|
135 | - */ |
|
136 | - private function check_directory($dirpath) |
|
137 | - { |
|
138 | - $dirpath = (string) $dirpath; |
|
139 | - $file_exists = file_exists($dirpath); |
|
140 | - $is_writable = wp_is_writable($dirpath); |
|
141 | - |
|
142 | - // If the configured setting path exists and is writeable, use it. |
|
143 | - if ($file_exists && $is_writable) { |
|
144 | - return $dirpath; |
|
145 | - } |
|
146 | - |
|
147 | - // Otherwise, try and log default errors |
|
148 | - if (!$file_exists) { |
|
149 | - $this->log('The defined logging directory does not exist: '.$dirpath, __METHOD__, 'error'); |
|
150 | - } |
|
151 | - |
|
152 | - if (!$is_writable) { |
|
153 | - $this->log('The defined logging directory exists but could not be written to: '.$dirpath, __METHOD__, 'error'); |
|
154 | - } |
|
155 | - |
|
156 | - return false; |
|
157 | - } |
|
158 | - |
|
159 | - /** |
|
160 | - * Returns the directory to use for logging if not defined by Config. Creates one if it doesn't exist. |
|
161 | - * |
|
162 | - * Note: Created directories are protected by an index.html file to prevent browsing. |
|
163 | - * |
|
164 | - * @return false|string Directory path, if exists; False if failure. |
|
165 | - */ |
|
166 | - private function maybe_make_logging_directory() |
|
167 | - { |
|
168 | - $upload_dir = wp_upload_dir(); |
|
169 | - |
|
170 | - $log_dir = trailingslashit($upload_dir['basedir']).self::DIRECTORY_PATH; |
|
171 | - |
|
172 | - // Directory exists; return early |
|
173 | - if (file_exists($log_dir)) { |
|
174 | - $this->prevent_directory_browsing($log_dir); |
|
175 | - |
|
176 | - return $log_dir; |
|
177 | - } |
|
178 | - |
|
179 | - // Create the folder using wp_mkdir_p() instead of relying on KLogger |
|
180 | - $folder_created = wp_mkdir_p($log_dir); |
|
181 | - |
|
182 | - // Something went wrong mapping the directory |
|
183 | - if (!$folder_created) { |
|
184 | - $this->log('The log directory could not be created: '.$log_dir, __METHOD__, 'error'); |
|
185 | - |
|
186 | - return false; |
|
187 | - } |
|
188 | - |
|
189 | - // Protect directory from being browsed by adding index.html |
|
190 | - $this->prevent_directory_browsing($log_dir); |
|
191 | - |
|
192 | - // Make sure the new log directory can be written to |
|
193 | - return $log_dir; |
|
194 | - } |
|
195 | - |
|
196 | - /** |
|
197 | - * Prevent browsing a directory by adding an index.html file to it. |
|
198 | - * |
|
199 | - * Code inspired by @see wp_privacy_generate_personal_data_export_file() |
|
200 | - * |
|
201 | - * @param string $dirpath Path to directory to protect (in this case, logging) |
|
202 | - * |
|
203 | - * @return bool True: File exists or was created; False: file could not be created. |
|
204 | - */ |
|
205 | - private function prevent_directory_browsing($dirpath) |
|
206 | - { |
|
207 | - |
|
208 | - // Protect export folder from browsing. |
|
209 | - $index_pathname = $dirpath.'index.html'; |
|
210 | - |
|
211 | - if (file_exists($index_pathname)) { |
|
212 | - return true; |
|
213 | - } |
|
214 | - |
|
215 | - $file = fopen($index_pathname, 'w'); |
|
216 | - |
|
217 | - if (false === $file) { |
|
218 | - $this->log('Unable to protect directory from browsing.', __METHOD__, 'error'); |
|
219 | - |
|
220 | - return false; |
|
221 | - } |
|
222 | - |
|
223 | - fwrite($file, '<!-- Silence is golden. TrustedLogin is also pretty great. -->'); |
|
224 | - fclose($file); |
|
225 | - |
|
226 | - return true; |
|
227 | - } |
|
228 | - |
|
229 | - /** |
|
230 | - * Returns whether logging is enabled. |
|
231 | - * |
|
232 | - * @return bool |
|
233 | - */ |
|
234 | - public function is_enabled() |
|
235 | - { |
|
236 | - $is_enabled = !empty($this->logging_enabled); |
|
237 | - |
|
238 | - /** |
|
239 | - * Filter: Whether debug logging is enabled in TrustedLogin Client. |
|
240 | - * |
|
241 | - * @since 1.0.0 |
|
242 | - * |
|
243 | - * @param bool $debug_mode Default: false |
|
244 | - */ |
|
245 | - $is_enabled = apply_filters('trustedlogin/'.$this->ns.'/logging/enabled', $is_enabled); |
|
246 | - |
|
247 | - return (bool) $is_enabled; |
|
248 | - } |
|
249 | - |
|
250 | - /** |
|
251 | - * @see https://github.com/php-fig/log/blob/master/Psr/Log/LogLevel.php for log levels |
|
252 | - * |
|
253 | - * @param string|\WP_Error $message Message or error to log. If a WP_Error is passed, $data is ignored. |
|
254 | - * @param string $method Method where the log was called |
|
255 | - * @param string $level PSR-3 log level |
|
256 | - * @param \WP_Error|\Exception|mixed $data Optional. Error data. Ignored if $message is WP_Error. |
|
257 | - */ |
|
258 | - public function log($message = '', $method = '', $level = 'debug', $data = []) |
|
259 | - { |
|
260 | - if (!$this->is_enabled()) { |
|
261 | - return; |
|
262 | - } |
|
263 | - |
|
264 | - $levels = ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug']; |
|
265 | - |
|
266 | - if (!in_array($level, $levels)) { |
|
267 | - $this->log(sprintf('Invalid level passed by %s method: %s', $method, $level), __METHOD__, 'error'); |
|
268 | - |
|
269 | - $level = 'debug'; // Continue processing original log |
|
270 | - } |
|
271 | - |
|
272 | - $log_message = $message; |
|
273 | - |
|
274 | - if (is_wp_error($log_message)) { |
|
275 | - $data = $log_message; // Store WP_Error as extra data. |
|
276 | - $log_message = ''; // The message will be constructed below. |
|
277 | - } |
|
278 | - |
|
279 | - if (!is_string($log_message)) { |
|
280 | - $log_message = print_r($log_message, true); |
|
281 | - } |
|
282 | - |
|
283 | - if (is_wp_error($data)) { |
|
284 | - $log_message .= sprintf('[%s] %s', $data->get_error_code(), $data->get_error_message()); |
|
285 | - } |
|
286 | - |
|
287 | - if ($data instanceof \Exception) { |
|
288 | - $log_message .= sprintf('[%s] %s', $data->getCode(), $data->getMessage()); |
|
289 | - } |
|
290 | - |
|
291 | - // Keep PSR-4 compatible |
|
292 | - if ($data && !is_array($data)) { |
|
293 | - $data = [$data]; |
|
294 | - } |
|
295 | - |
|
296 | - do_action('trustedlogin/'.$this->ns.'/logging/log', $message, $method, $level, $data); |
|
297 | - do_action('trustedlogin/'.$this->ns.'/logging/log_'.$level, $message, $method, $data); |
|
298 | - |
|
299 | - // If logging is in place, don't use the error_log |
|
300 | - if (has_action('trustedlogin/'.$this->ns.'/logging/log') || has_action('trustedlogin/'.$this->ns.'/logging/log_'.$level)) { |
|
301 | - return; |
|
302 | - } |
|
303 | - |
|
304 | - // The logger class didn't load for some reason |
|
305 | - if (!$this->klogger) { |
|
306 | - $wp_debug = defined('WP_DEBUG') && WP_DEBUG; |
|
307 | - $wp_debug_log = defined('WP_DEBUG_LOG') && WP_DEBUG_LOG; |
|
308 | - |
|
309 | - // If WP_DEBUG and WP_DEBUG_LOG are enabled, log errors to that file. |
|
310 | - if ($wp_debug && $wp_debug_log) { |
|
311 | - if (!empty($data)) { |
|
312 | - $log_message .= ' Error data: '.print_r($data, true); |
|
313 | - } |
|
314 | - |
|
315 | - error_log($method.' ('.$level.'): '.$log_message); |
|
316 | - } |
|
317 | - |
|
318 | - return; |
|
319 | - } |
|
320 | - |
|
321 | - $this->klogger->{$level}($log_message, (array) $data); |
|
322 | - } |
|
19 | + /** |
|
20 | + * Path to logging directory (inside the WP Uploads base dir). |
|
21 | + */ |
|
22 | + const DIRECTORY_PATH = 'trustedlogin-logs/'; |
|
23 | + |
|
24 | + /** |
|
25 | + * @var string Namespace for the vendor |
|
26 | + */ |
|
27 | + private $ns; |
|
28 | + |
|
29 | + /** |
|
30 | + * @var bool |
|
31 | + */ |
|
32 | + private $logging_enabled = false; |
|
33 | + |
|
34 | + /** |
|
35 | + * @var Logger|null|false Null: not instantiated; False: failed to instantiate. |
|
36 | + */ |
|
37 | + private $klogger = null; |
|
38 | + |
|
39 | + /** |
|
40 | + * Logger constructor. |
|
41 | + */ |
|
42 | + public function __construct(Config $config) |
|
43 | + { |
|
44 | + $this->ns = $config->ns(); |
|
45 | + |
|
46 | + $this->logging_enabled = $config->get_setting('logging/enabled', false); |
|
47 | + |
|
48 | + $this->klogger = $this->setup_klogger($config); |
|
49 | + } |
|
50 | + |
|
51 | + /** |
|
52 | + * Attempts to initialize KLogger logging. |
|
53 | + * |
|
54 | + * @param Config $config |
|
55 | + * |
|
56 | + * @return false|Logger |
|
57 | + */ |
|
58 | + private function setup_klogger($config) |
|
59 | + { |
|
60 | + if (!class_exists('GravityView\Katzgrau\KLogger\Logger')) { |
|
61 | + $this->log('KLogger not found.', __METHOD__, 'error'); |
|
62 | + |
|
63 | + return false; |
|
64 | + } |
|
65 | + |
|
66 | + $logging_directory = null; |
|
67 | + |
|
68 | + $configured_logging_dir = $config->get_setting('logging/directory', ''); |
|
69 | + |
|
70 | + if (!empty($configured_logging_dir)) { |
|
71 | + $logging_directory = $this->check_directory($configured_logging_dir); |
|
72 | + |
|
73 | + if (!$logging_directory) { |
|
74 | + return false; |
|
75 | + } |
|
76 | + } |
|
77 | + |
|
78 | + if (!$logging_directory) { |
|
79 | + $logging_directory = $this->maybe_make_logging_directory(); |
|
80 | + } |
|
81 | + |
|
82 | + // Directory cannot be found or created. Cannot log. |
|
83 | + if (!$logging_directory) { |
|
84 | + return false; |
|
85 | + } |
|
86 | + |
|
87 | + // Directory cannot be written to |
|
88 | + if (!$this->check_directory($logging_directory)) { |
|
89 | + return false; |
|
90 | + } |
|
91 | + |
|
92 | + try { |
|
93 | + $DateTime = new \DateTime('@'.time()); |
|
94 | + |
|
95 | + // Filename hash changes every day, make it harder to guess |
|
96 | + $filename_hash_data = $this->ns.home_url('/').$DateTime->format('z'); |
|
97 | + |
|
98 | + $default_options = [ |
|
99 | + 'extension' => 'log', |
|
100 | + 'dateFormat' => 'Y-m-d G:i:s.u', |
|
101 | + 'filename' => sprintf('trustedlogin-client-debug-%s-%s', $DateTime->format('Y-m-d'), wp_hash($filename_hash_data)), |
|
102 | + 'flushFrequency' => false, |
|
103 | + 'logFormat' => false, |
|
104 | + 'appendContext' => true, |
|
105 | + ]; |
|
106 | + |
|
107 | + $settings_options = $config->get_setting('logging/options', $default_options); |
|
108 | + |
|
109 | + $options = wp_parse_args($settings_options, $default_options); |
|
110 | + |
|
111 | + $klogger = new Logger( |
|
112 | + $logging_directory, |
|
113 | + $config->get_setting('logging/threshold', 'notice'), |
|
114 | + $options |
|
115 | + ); |
|
116 | + } catch (\RuntimeException $exception) { |
|
117 | + $this->log('Could not initialize KLogger: '.$exception->getMessage(), __METHOD__, 'error'); |
|
118 | + |
|
119 | + return false; |
|
120 | + } catch (\Exception $exception) { |
|
121 | + $this->log('DateTime could not be created: '.$exception->getMessage(), __METHOD__, 'error'); |
|
122 | + |
|
123 | + return false; |
|
124 | + } |
|
125 | + |
|
126 | + return $klogger; |
|
127 | + } |
|
128 | + |
|
129 | + /** |
|
130 | + * Checks whether a path exists and is writable. |
|
131 | + * |
|
132 | + * @param string $dirpath Path to directory |
|
133 | + * |
|
134 | + * @return bool|string If exists and writable, returns original string. Otherwise, returns false. |
|
135 | + */ |
|
136 | + private function check_directory($dirpath) |
|
137 | + { |
|
138 | + $dirpath = (string) $dirpath; |
|
139 | + $file_exists = file_exists($dirpath); |
|
140 | + $is_writable = wp_is_writable($dirpath); |
|
141 | + |
|
142 | + // If the configured setting path exists and is writeable, use it. |
|
143 | + if ($file_exists && $is_writable) { |
|
144 | + return $dirpath; |
|
145 | + } |
|
146 | + |
|
147 | + // Otherwise, try and log default errors |
|
148 | + if (!$file_exists) { |
|
149 | + $this->log('The defined logging directory does not exist: '.$dirpath, __METHOD__, 'error'); |
|
150 | + } |
|
151 | + |
|
152 | + if (!$is_writable) { |
|
153 | + $this->log('The defined logging directory exists but could not be written to: '.$dirpath, __METHOD__, 'error'); |
|
154 | + } |
|
155 | + |
|
156 | + return false; |
|
157 | + } |
|
158 | + |
|
159 | + /** |
|
160 | + * Returns the directory to use for logging if not defined by Config. Creates one if it doesn't exist. |
|
161 | + * |
|
162 | + * Note: Created directories are protected by an index.html file to prevent browsing. |
|
163 | + * |
|
164 | + * @return false|string Directory path, if exists; False if failure. |
|
165 | + */ |
|
166 | + private function maybe_make_logging_directory() |
|
167 | + { |
|
168 | + $upload_dir = wp_upload_dir(); |
|
169 | + |
|
170 | + $log_dir = trailingslashit($upload_dir['basedir']).self::DIRECTORY_PATH; |
|
171 | + |
|
172 | + // Directory exists; return early |
|
173 | + if (file_exists($log_dir)) { |
|
174 | + $this->prevent_directory_browsing($log_dir); |
|
175 | + |
|
176 | + return $log_dir; |
|
177 | + } |
|
178 | + |
|
179 | + // Create the folder using wp_mkdir_p() instead of relying on KLogger |
|
180 | + $folder_created = wp_mkdir_p($log_dir); |
|
181 | + |
|
182 | + // Something went wrong mapping the directory |
|
183 | + if (!$folder_created) { |
|
184 | + $this->log('The log directory could not be created: '.$log_dir, __METHOD__, 'error'); |
|
185 | + |
|
186 | + return false; |
|
187 | + } |
|
188 | + |
|
189 | + // Protect directory from being browsed by adding index.html |
|
190 | + $this->prevent_directory_browsing($log_dir); |
|
191 | + |
|
192 | + // Make sure the new log directory can be written to |
|
193 | + return $log_dir; |
|
194 | + } |
|
195 | + |
|
196 | + /** |
|
197 | + * Prevent browsing a directory by adding an index.html file to it. |
|
198 | + * |
|
199 | + * Code inspired by @see wp_privacy_generate_personal_data_export_file() |
|
200 | + * |
|
201 | + * @param string $dirpath Path to directory to protect (in this case, logging) |
|
202 | + * |
|
203 | + * @return bool True: File exists or was created; False: file could not be created. |
|
204 | + */ |
|
205 | + private function prevent_directory_browsing($dirpath) |
|
206 | + { |
|
207 | + |
|
208 | + // Protect export folder from browsing. |
|
209 | + $index_pathname = $dirpath.'index.html'; |
|
210 | + |
|
211 | + if (file_exists($index_pathname)) { |
|
212 | + return true; |
|
213 | + } |
|
214 | + |
|
215 | + $file = fopen($index_pathname, 'w'); |
|
216 | + |
|
217 | + if (false === $file) { |
|
218 | + $this->log('Unable to protect directory from browsing.', __METHOD__, 'error'); |
|
219 | + |
|
220 | + return false; |
|
221 | + } |
|
222 | + |
|
223 | + fwrite($file, '<!-- Silence is golden. TrustedLogin is also pretty great. -->'); |
|
224 | + fclose($file); |
|
225 | + |
|
226 | + return true; |
|
227 | + } |
|
228 | + |
|
229 | + /** |
|
230 | + * Returns whether logging is enabled. |
|
231 | + * |
|
232 | + * @return bool |
|
233 | + */ |
|
234 | + public function is_enabled() |
|
235 | + { |
|
236 | + $is_enabled = !empty($this->logging_enabled); |
|
237 | + |
|
238 | + /** |
|
239 | + * Filter: Whether debug logging is enabled in TrustedLogin Client. |
|
240 | + * |
|
241 | + * @since 1.0.0 |
|
242 | + * |
|
243 | + * @param bool $debug_mode Default: false |
|
244 | + */ |
|
245 | + $is_enabled = apply_filters('trustedlogin/'.$this->ns.'/logging/enabled', $is_enabled); |
|
246 | + |
|
247 | + return (bool) $is_enabled; |
|
248 | + } |
|
249 | + |
|
250 | + /** |
|
251 | + * @see https://github.com/php-fig/log/blob/master/Psr/Log/LogLevel.php for log levels |
|
252 | + * |
|
253 | + * @param string|\WP_Error $message Message or error to log. If a WP_Error is passed, $data is ignored. |
|
254 | + * @param string $method Method where the log was called |
|
255 | + * @param string $level PSR-3 log level |
|
256 | + * @param \WP_Error|\Exception|mixed $data Optional. Error data. Ignored if $message is WP_Error. |
|
257 | + */ |
|
258 | + public function log($message = '', $method = '', $level = 'debug', $data = []) |
|
259 | + { |
|
260 | + if (!$this->is_enabled()) { |
|
261 | + return; |
|
262 | + } |
|
263 | + |
|
264 | + $levels = ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug']; |
|
265 | + |
|
266 | + if (!in_array($level, $levels)) { |
|
267 | + $this->log(sprintf('Invalid level passed by %s method: %s', $method, $level), __METHOD__, 'error'); |
|
268 | + |
|
269 | + $level = 'debug'; // Continue processing original log |
|
270 | + } |
|
271 | + |
|
272 | + $log_message = $message; |
|
273 | + |
|
274 | + if (is_wp_error($log_message)) { |
|
275 | + $data = $log_message; // Store WP_Error as extra data. |
|
276 | + $log_message = ''; // The message will be constructed below. |
|
277 | + } |
|
278 | + |
|
279 | + if (!is_string($log_message)) { |
|
280 | + $log_message = print_r($log_message, true); |
|
281 | + } |
|
282 | + |
|
283 | + if (is_wp_error($data)) { |
|
284 | + $log_message .= sprintf('[%s] %s', $data->get_error_code(), $data->get_error_message()); |
|
285 | + } |
|
286 | + |
|
287 | + if ($data instanceof \Exception) { |
|
288 | + $log_message .= sprintf('[%s] %s', $data->getCode(), $data->getMessage()); |
|
289 | + } |
|
290 | + |
|
291 | + // Keep PSR-4 compatible |
|
292 | + if ($data && !is_array($data)) { |
|
293 | + $data = [$data]; |
|
294 | + } |
|
295 | + |
|
296 | + do_action('trustedlogin/'.$this->ns.'/logging/log', $message, $method, $level, $data); |
|
297 | + do_action('trustedlogin/'.$this->ns.'/logging/log_'.$level, $message, $method, $data); |
|
298 | + |
|
299 | + // If logging is in place, don't use the error_log |
|
300 | + if (has_action('trustedlogin/'.$this->ns.'/logging/log') || has_action('trustedlogin/'.$this->ns.'/logging/log_'.$level)) { |
|
301 | + return; |
|
302 | + } |
|
303 | + |
|
304 | + // The logger class didn't load for some reason |
|
305 | + if (!$this->klogger) { |
|
306 | + $wp_debug = defined('WP_DEBUG') && WP_DEBUG; |
|
307 | + $wp_debug_log = defined('WP_DEBUG_LOG') && WP_DEBUG_LOG; |
|
308 | + |
|
309 | + // If WP_DEBUG and WP_DEBUG_LOG are enabled, log errors to that file. |
|
310 | + if ($wp_debug && $wp_debug_log) { |
|
311 | + if (!empty($data)) { |
|
312 | + $log_message .= ' Error data: '.print_r($data, true); |
|
313 | + } |
|
314 | + |
|
315 | + error_log($method.' ('.$level.'): '.$log_message); |
|
316 | + } |
|
317 | + |
|
318 | + return; |
|
319 | + } |
|
320 | + |
|
321 | + $this->klogger->{$level}($log_message, (array) $data); |
|
322 | + } |
|
323 | 323 | } |
@@ -39,13 +39,13 @@ discard block |
||
39 | 39 | /** |
40 | 40 | * Logger constructor. |
41 | 41 | */ |
42 | - public function __construct(Config $config) |
|
42 | + public function __construct( Config $config ) |
|
43 | 43 | { |
44 | 44 | $this->ns = $config->ns(); |
45 | 45 | |
46 | - $this->logging_enabled = $config->get_setting('logging/enabled', false); |
|
46 | + $this->logging_enabled = $config->get_setting( 'logging/enabled', false ); |
|
47 | 47 | |
48 | - $this->klogger = $this->setup_klogger($config); |
|
48 | + $this->klogger = $this->setup_klogger( $config ); |
|
49 | 49 | } |
50 | 50 | |
51 | 51 | /** |
@@ -55,70 +55,70 @@ discard block |
||
55 | 55 | * |
56 | 56 | * @return false|Logger |
57 | 57 | */ |
58 | - private function setup_klogger($config) |
|
58 | + private function setup_klogger( $config ) |
|
59 | 59 | { |
60 | - if (!class_exists('GravityView\Katzgrau\KLogger\Logger')) { |
|
61 | - $this->log('KLogger not found.', __METHOD__, 'error'); |
|
60 | + if ( ! class_exists( 'GravityView\Katzgrau\KLogger\Logger' ) ) { |
|
61 | + $this->log( 'KLogger not found.', __METHOD__, 'error' ); |
|
62 | 62 | |
63 | 63 | return false; |
64 | 64 | } |
65 | 65 | |
66 | 66 | $logging_directory = null; |
67 | 67 | |
68 | - $configured_logging_dir = $config->get_setting('logging/directory', ''); |
|
68 | + $configured_logging_dir = $config->get_setting( 'logging/directory', '' ); |
|
69 | 69 | |
70 | - if (!empty($configured_logging_dir)) { |
|
71 | - $logging_directory = $this->check_directory($configured_logging_dir); |
|
70 | + if ( ! empty( $configured_logging_dir ) ) { |
|
71 | + $logging_directory = $this->check_directory( $configured_logging_dir ); |
|
72 | 72 | |
73 | - if (!$logging_directory) { |
|
73 | + if ( ! $logging_directory ) { |
|
74 | 74 | return false; |
75 | 75 | } |
76 | 76 | } |
77 | 77 | |
78 | - if (!$logging_directory) { |
|
78 | + if ( ! $logging_directory ) { |
|
79 | 79 | $logging_directory = $this->maybe_make_logging_directory(); |
80 | 80 | } |
81 | 81 | |
82 | 82 | // Directory cannot be found or created. Cannot log. |
83 | - if (!$logging_directory) { |
|
83 | + if ( ! $logging_directory ) { |
|
84 | 84 | return false; |
85 | 85 | } |
86 | 86 | |
87 | 87 | // Directory cannot be written to |
88 | - if (!$this->check_directory($logging_directory)) { |
|
88 | + if ( ! $this->check_directory( $logging_directory ) ) { |
|
89 | 89 | return false; |
90 | 90 | } |
91 | 91 | |
92 | 92 | try { |
93 | - $DateTime = new \DateTime('@'.time()); |
|
93 | + $DateTime = new \DateTime( '@' . time() ); |
|
94 | 94 | |
95 | 95 | // Filename hash changes every day, make it harder to guess |
96 | - $filename_hash_data = $this->ns.home_url('/').$DateTime->format('z'); |
|
96 | + $filename_hash_data = $this->ns . home_url( '/' ) . $DateTime->format( 'z' ); |
|
97 | 97 | |
98 | 98 | $default_options = [ |
99 | 99 | 'extension' => 'log', |
100 | 100 | 'dateFormat' => 'Y-m-d G:i:s.u', |
101 | - 'filename' => sprintf('trustedlogin-client-debug-%s-%s', $DateTime->format('Y-m-d'), wp_hash($filename_hash_data)), |
|
101 | + 'filename' => sprintf( 'trustedlogin-client-debug-%s-%s', $DateTime->format( 'Y-m-d' ), wp_hash( $filename_hash_data ) ), |
|
102 | 102 | 'flushFrequency' => false, |
103 | 103 | 'logFormat' => false, |
104 | 104 | 'appendContext' => true, |
105 | 105 | ]; |
106 | 106 | |
107 | - $settings_options = $config->get_setting('logging/options', $default_options); |
|
107 | + $settings_options = $config->get_setting( 'logging/options', $default_options ); |
|
108 | 108 | |
109 | - $options = wp_parse_args($settings_options, $default_options); |
|
109 | + $options = wp_parse_args( $settings_options, $default_options ); |
|
110 | 110 | |
111 | 111 | $klogger = new Logger( |
112 | 112 | $logging_directory, |
113 | - $config->get_setting('logging/threshold', 'notice'), |
|
113 | + $config->get_setting( 'logging/threshold', 'notice' ), |
|
114 | 114 | $options |
115 | 115 | ); |
116 | - } catch (\RuntimeException $exception) { |
|
117 | - $this->log('Could not initialize KLogger: '.$exception->getMessage(), __METHOD__, 'error'); |
|
116 | + } catch ( \RuntimeException $exception ) { |
|
117 | + $this->log( 'Could not initialize KLogger: ' . $exception->getMessage(), __METHOD__, 'error' ); |
|
118 | 118 | |
119 | 119 | return false; |
120 | - } catch (\Exception $exception) { |
|
121 | - $this->log('DateTime could not be created: '.$exception->getMessage(), __METHOD__, 'error'); |
|
120 | + } catch ( \Exception $exception ) { |
|
121 | + $this->log( 'DateTime could not be created: ' . $exception->getMessage(), __METHOD__, 'error' ); |
|
122 | 122 | |
123 | 123 | return false; |
124 | 124 | } |
@@ -133,24 +133,24 @@ discard block |
||
133 | 133 | * |
134 | 134 | * @return bool|string If exists and writable, returns original string. Otherwise, returns false. |
135 | 135 | */ |
136 | - private function check_directory($dirpath) |
|
136 | + private function check_directory( $dirpath ) |
|
137 | 137 | { |
138 | - $dirpath = (string) $dirpath; |
|
139 | - $file_exists = file_exists($dirpath); |
|
140 | - $is_writable = wp_is_writable($dirpath); |
|
138 | + $dirpath = (string)$dirpath; |
|
139 | + $file_exists = file_exists( $dirpath ); |
|
140 | + $is_writable = wp_is_writable( $dirpath ); |
|
141 | 141 | |
142 | 142 | // If the configured setting path exists and is writeable, use it. |
143 | - if ($file_exists && $is_writable) { |
|
143 | + if ( $file_exists && $is_writable ) { |
|
144 | 144 | return $dirpath; |
145 | 145 | } |
146 | 146 | |
147 | 147 | // Otherwise, try and log default errors |
148 | - if (!$file_exists) { |
|
149 | - $this->log('The defined logging directory does not exist: '.$dirpath, __METHOD__, 'error'); |
|
148 | + if ( ! $file_exists ) { |
|
149 | + $this->log( 'The defined logging directory does not exist: ' . $dirpath, __METHOD__, 'error' ); |
|
150 | 150 | } |
151 | 151 | |
152 | - if (!$is_writable) { |
|
153 | - $this->log('The defined logging directory exists but could not be written to: '.$dirpath, __METHOD__, 'error'); |
|
152 | + if ( ! $is_writable ) { |
|
153 | + $this->log( 'The defined logging directory exists but could not be written to: ' . $dirpath, __METHOD__, 'error' ); |
|
154 | 154 | } |
155 | 155 | |
156 | 156 | return false; |
@@ -167,27 +167,27 @@ discard block |
||
167 | 167 | { |
168 | 168 | $upload_dir = wp_upload_dir(); |
169 | 169 | |
170 | - $log_dir = trailingslashit($upload_dir['basedir']).self::DIRECTORY_PATH; |
|
170 | + $log_dir = trailingslashit( $upload_dir[ 'basedir' ] ) . self::DIRECTORY_PATH; |
|
171 | 171 | |
172 | 172 | // Directory exists; return early |
173 | - if (file_exists($log_dir)) { |
|
174 | - $this->prevent_directory_browsing($log_dir); |
|
173 | + if ( file_exists( $log_dir ) ) { |
|
174 | + $this->prevent_directory_browsing( $log_dir ); |
|
175 | 175 | |
176 | 176 | return $log_dir; |
177 | 177 | } |
178 | 178 | |
179 | 179 | // Create the folder using wp_mkdir_p() instead of relying on KLogger |
180 | - $folder_created = wp_mkdir_p($log_dir); |
|
180 | + $folder_created = wp_mkdir_p( $log_dir ); |
|
181 | 181 | |
182 | 182 | // Something went wrong mapping the directory |
183 | - if (!$folder_created) { |
|
184 | - $this->log('The log directory could not be created: '.$log_dir, __METHOD__, 'error'); |
|
183 | + if ( ! $folder_created ) { |
|
184 | + $this->log( 'The log directory could not be created: ' . $log_dir, __METHOD__, 'error' ); |
|
185 | 185 | |
186 | 186 | return false; |
187 | 187 | } |
188 | 188 | |
189 | 189 | // Protect directory from being browsed by adding index.html |
190 | - $this->prevent_directory_browsing($log_dir); |
|
190 | + $this->prevent_directory_browsing( $log_dir ); |
|
191 | 191 | |
192 | 192 | // Make sure the new log directory can be written to |
193 | 193 | return $log_dir; |
@@ -202,26 +202,26 @@ discard block |
||
202 | 202 | * |
203 | 203 | * @return bool True: File exists or was created; False: file could not be created. |
204 | 204 | */ |
205 | - private function prevent_directory_browsing($dirpath) |
|
205 | + private function prevent_directory_browsing( $dirpath ) |
|
206 | 206 | { |
207 | 207 | |
208 | 208 | // Protect export folder from browsing. |
209 | - $index_pathname = $dirpath.'index.html'; |
|
209 | + $index_pathname = $dirpath . 'index.html'; |
|
210 | 210 | |
211 | - if (file_exists($index_pathname)) { |
|
211 | + if ( file_exists( $index_pathname ) ) { |
|
212 | 212 | return true; |
213 | 213 | } |
214 | 214 | |
215 | - $file = fopen($index_pathname, 'w'); |
|
215 | + $file = fopen( $index_pathname, 'w' ); |
|
216 | 216 | |
217 | - if (false === $file) { |
|
218 | - $this->log('Unable to protect directory from browsing.', __METHOD__, 'error'); |
|
217 | + if ( false === $file ) { |
|
218 | + $this->log( 'Unable to protect directory from browsing.', __METHOD__, 'error' ); |
|
219 | 219 | |
220 | 220 | return false; |
221 | 221 | } |
222 | 222 | |
223 | - fwrite($file, '<!-- Silence is golden. TrustedLogin is also pretty great. -->'); |
|
224 | - fclose($file); |
|
223 | + fwrite( $file, '<!-- Silence is golden. TrustedLogin is also pretty great. -->' ); |
|
224 | + fclose( $file ); |
|
225 | 225 | |
226 | 226 | return true; |
227 | 227 | } |
@@ -233,7 +233,7 @@ discard block |
||
233 | 233 | */ |
234 | 234 | public function is_enabled() |
235 | 235 | { |
236 | - $is_enabled = !empty($this->logging_enabled); |
|
236 | + $is_enabled = ! empty( $this->logging_enabled ); |
|
237 | 237 | |
238 | 238 | /** |
239 | 239 | * Filter: Whether debug logging is enabled in TrustedLogin Client. |
@@ -242,9 +242,9 @@ discard block |
||
242 | 242 | * |
243 | 243 | * @param bool $debug_mode Default: false |
244 | 244 | */ |
245 | - $is_enabled = apply_filters('trustedlogin/'.$this->ns.'/logging/enabled', $is_enabled); |
|
245 | + $is_enabled = apply_filters( 'trustedlogin/' . $this->ns . '/logging/enabled', $is_enabled ); |
|
246 | 246 | |
247 | - return (bool) $is_enabled; |
|
247 | + return (bool)$is_enabled; |
|
248 | 248 | } |
249 | 249 | |
250 | 250 | /** |
@@ -255,69 +255,69 @@ discard block |
||
255 | 255 | * @param string $level PSR-3 log level |
256 | 256 | * @param \WP_Error|\Exception|mixed $data Optional. Error data. Ignored if $message is WP_Error. |
257 | 257 | */ |
258 | - public function log($message = '', $method = '', $level = 'debug', $data = []) |
|
258 | + public function log( $message = '', $method = '', $level = 'debug', $data = [ ] ) |
|
259 | 259 | { |
260 | - if (!$this->is_enabled()) { |
|
260 | + if ( ! $this->is_enabled() ) { |
|
261 | 261 | return; |
262 | 262 | } |
263 | 263 | |
264 | - $levels = ['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug']; |
|
264 | + $levels = [ 'emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug' ]; |
|
265 | 265 | |
266 | - if (!in_array($level, $levels)) { |
|
267 | - $this->log(sprintf('Invalid level passed by %s method: %s', $method, $level), __METHOD__, 'error'); |
|
266 | + if ( ! in_array( $level, $levels ) ) { |
|
267 | + $this->log( sprintf( 'Invalid level passed by %s method: %s', $method, $level ), __METHOD__, 'error' ); |
|
268 | 268 | |
269 | 269 | $level = 'debug'; // Continue processing original log |
270 | 270 | } |
271 | 271 | |
272 | 272 | $log_message = $message; |
273 | 273 | |
274 | - if (is_wp_error($log_message)) { |
|
274 | + if ( is_wp_error( $log_message ) ) { |
|
275 | 275 | $data = $log_message; // Store WP_Error as extra data. |
276 | 276 | $log_message = ''; // The message will be constructed below. |
277 | 277 | } |
278 | 278 | |
279 | - if (!is_string($log_message)) { |
|
280 | - $log_message = print_r($log_message, true); |
|
279 | + if ( ! is_string( $log_message ) ) { |
|
280 | + $log_message = print_r( $log_message, true ); |
|
281 | 281 | } |
282 | 282 | |
283 | - if (is_wp_error($data)) { |
|
284 | - $log_message .= sprintf('[%s] %s', $data->get_error_code(), $data->get_error_message()); |
|
283 | + if ( is_wp_error( $data ) ) { |
|
284 | + $log_message .= sprintf( '[%s] %s', $data->get_error_code(), $data->get_error_message() ); |
|
285 | 285 | } |
286 | 286 | |
287 | - if ($data instanceof \Exception) { |
|
288 | - $log_message .= sprintf('[%s] %s', $data->getCode(), $data->getMessage()); |
|
287 | + if ( $data instanceof \Exception ) { |
|
288 | + $log_message .= sprintf( '[%s] %s', $data->getCode(), $data->getMessage() ); |
|
289 | 289 | } |
290 | 290 | |
291 | 291 | // Keep PSR-4 compatible |
292 | - if ($data && !is_array($data)) { |
|
293 | - $data = [$data]; |
|
292 | + if ( $data && ! is_array( $data ) ) { |
|
293 | + $data = [ $data ]; |
|
294 | 294 | } |
295 | 295 | |
296 | - do_action('trustedlogin/'.$this->ns.'/logging/log', $message, $method, $level, $data); |
|
297 | - do_action('trustedlogin/'.$this->ns.'/logging/log_'.$level, $message, $method, $data); |
|
296 | + do_action( 'trustedlogin/' . $this->ns . '/logging/log', $message, $method, $level, $data ); |
|
297 | + do_action( 'trustedlogin/' . $this->ns . '/logging/log_' . $level, $message, $method, $data ); |
|
298 | 298 | |
299 | 299 | // If logging is in place, don't use the error_log |
300 | - if (has_action('trustedlogin/'.$this->ns.'/logging/log') || has_action('trustedlogin/'.$this->ns.'/logging/log_'.$level)) { |
|
300 | + if ( has_action( 'trustedlogin/' . $this->ns . '/logging/log' ) || has_action( 'trustedlogin/' . $this->ns . '/logging/log_' . $level ) ) { |
|
301 | 301 | return; |
302 | 302 | } |
303 | 303 | |
304 | 304 | // The logger class didn't load for some reason |
305 | - if (!$this->klogger) { |
|
306 | - $wp_debug = defined('WP_DEBUG') && WP_DEBUG; |
|
307 | - $wp_debug_log = defined('WP_DEBUG_LOG') && WP_DEBUG_LOG; |
|
305 | + if ( ! $this->klogger ) { |
|
306 | + $wp_debug = defined( 'WP_DEBUG' ) && WP_DEBUG; |
|
307 | + $wp_debug_log = defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG; |
|
308 | 308 | |
309 | 309 | // If WP_DEBUG and WP_DEBUG_LOG are enabled, log errors to that file. |
310 | - if ($wp_debug && $wp_debug_log) { |
|
311 | - if (!empty($data)) { |
|
312 | - $log_message .= ' Error data: '.print_r($data, true); |
|
310 | + if ( $wp_debug && $wp_debug_log ) { |
|
311 | + if ( ! empty( $data ) ) { |
|
312 | + $log_message .= ' Error data: ' . print_r( $data, true ); |
|
313 | 313 | } |
314 | 314 | |
315 | - error_log($method.' ('.$level.'): '.$log_message); |
|
315 | + error_log( $method . ' (' . $level . '): ' . $log_message ); |
|
316 | 316 | } |
317 | 317 | |
318 | 318 | return; |
319 | 319 | } |
320 | 320 | |
321 | - $this->klogger->{$level}($log_message, (array) $data); |
|
321 | + $this->klogger->{$level}( $log_message, (array)$data ); |
|
322 | 322 | } |
323 | 323 | } |
@@ -14,8 +14,7 @@ discard block |
||
14 | 14 | |
15 | 15 | use GravityView\Katzgrau\KLogger\Logger; |
16 | 16 | |
17 | -class Logging |
|
18 | -{ |
|
17 | +class Logging { |
|
19 | 18 | /** |
20 | 19 | * Path to logging directory (inside the WP Uploads base dir). |
21 | 20 | */ |
@@ -39,8 +38,7 @@ discard block |
||
39 | 38 | /** |
40 | 39 | * Logger constructor. |
41 | 40 | */ |
42 | - public function __construct(Config $config) |
|
43 | - { |
|
41 | + public function __construct(Config $config) { |
|
44 | 42 | $this->ns = $config->ns(); |
45 | 43 | |
46 | 44 | $this->logging_enabled = $config->get_setting('logging/enabled', false); |
@@ -55,8 +53,7 @@ discard block |
||
55 | 53 | * |
56 | 54 | * @return false|Logger |
57 | 55 | */ |
58 | - private function setup_klogger($config) |
|
59 | - { |
|
56 | + private function setup_klogger($config) { |
|
60 | 57 | if (!class_exists('GravityView\Katzgrau\KLogger\Logger')) { |
61 | 58 | $this->log('KLogger not found.', __METHOD__, 'error'); |
62 | 59 | |
@@ -133,8 +130,7 @@ discard block |
||
133 | 130 | * |
134 | 131 | * @return bool|string If exists and writable, returns original string. Otherwise, returns false. |
135 | 132 | */ |
136 | - private function check_directory($dirpath) |
|
137 | - { |
|
133 | + private function check_directory($dirpath) { |
|
138 | 134 | $dirpath = (string) $dirpath; |
139 | 135 | $file_exists = file_exists($dirpath); |
140 | 136 | $is_writable = wp_is_writable($dirpath); |
@@ -163,8 +159,7 @@ discard block |
||
163 | 159 | * |
164 | 160 | * @return false|string Directory path, if exists; False if failure. |
165 | 161 | */ |
166 | - private function maybe_make_logging_directory() |
|
167 | - { |
|
162 | + private function maybe_make_logging_directory() { |
|
168 | 163 | $upload_dir = wp_upload_dir(); |
169 | 164 | |
170 | 165 | $log_dir = trailingslashit($upload_dir['basedir']).self::DIRECTORY_PATH; |
@@ -202,8 +197,7 @@ discard block |
||
202 | 197 | * |
203 | 198 | * @return bool True: File exists or was created; False: file could not be created. |
204 | 199 | */ |
205 | - private function prevent_directory_browsing($dirpath) |
|
206 | - { |
|
200 | + private function prevent_directory_browsing($dirpath) { |
|
207 | 201 | |
208 | 202 | // Protect export folder from browsing. |
209 | 203 | $index_pathname = $dirpath.'index.html'; |
@@ -231,8 +225,7 @@ discard block |
||
231 | 225 | * |
232 | 226 | * @return bool |
233 | 227 | */ |
234 | - public function is_enabled() |
|
235 | - { |
|
228 | + public function is_enabled() { |
|
236 | 229 | $is_enabled = !empty($this->logging_enabled); |
237 | 230 | |
238 | 231 | /** |
@@ -255,8 +248,7 @@ discard block |
||
255 | 248 | * @param string $level PSR-3 log level |
256 | 249 | * @param \WP_Error|\Exception|mixed $data Optional. Error data. Ignored if $message is WP_Error. |
257 | 250 | */ |
258 | - public function log($message = '', $method = '', $level = 'debug', $data = []) |
|
259 | - { |
|
251 | + public function log($message = '', $method = '', $level = 'debug', $data = []) { |
|
260 | 252 | if (!$this->is_enabled()) { |
261 | 253 | return; |
262 | 254 | } |
@@ -14,7 +14,7 @@ discard block |
||
14 | 14 | |
15 | 15 | // Exit if accessed directly |
16 | 16 | if (!defined('ABSPATH')) { |
17 | - exit; |
|
17 | + exit; |
|
18 | 18 | } |
19 | 19 | |
20 | 20 | use Exception; |
@@ -25,302 +25,302 @@ discard block |
||
25 | 25 | */ |
26 | 26 | final class Remote |
27 | 27 | { |
28 | - /** |
|
29 | - * @var string The API url for the TrustedLogin SaaS Platform (with trailing slash) |
|
30 | - * |
|
31 | - * @since 1.0.0 |
|
32 | - */ |
|
33 | - const API_URL = 'https://app.trustedlogin.com/api/v1/'; |
|
34 | - |
|
35 | - /** |
|
36 | - * @var Config |
|
37 | - */ |
|
38 | - private $config; |
|
39 | - |
|
40 | - /** |
|
41 | - * @var Logging |
|
42 | - */ |
|
43 | - private $logging; |
|
44 | - |
|
45 | - /** |
|
46 | - * SupportUser constructor. |
|
47 | - */ |
|
48 | - public function __construct(Config $config, Logging $logging) |
|
49 | - { |
|
50 | - $this->config = $config; |
|
51 | - $this->logging = $logging; |
|
52 | - } |
|
53 | - |
|
54 | - public function init() |
|
55 | - { |
|
56 | - add_action('trustedlogin/'.$this->config->ns().'/access/created', [$this, 'maybe_send_webhook']); |
|
57 | - add_action('trustedlogin/'.$this->config->ns().'/access/extended', [$this, 'maybe_send_webhook']); |
|
58 | - add_action('trustedlogin/'.$this->config->ns().'/access/revoked', [$this, 'maybe_send_webhook']); |
|
59 | - add_action('trustedlogin/'.$this->config->ns().'/logged_in', [$this, 'maybe_send_webhook']); |
|
60 | - } |
|
61 | - |
|
62 | - /** |
|
63 | - * POSTs to `webhook_url`, if defined in the configuration array. |
|
64 | - * |
|
65 | - * @since 1.0.0 |
|
66 | - * |
|
67 | - * @param array $data { |
|
68 | - * |
|
69 | - * @var string $url The site URL as returned by get_site_url() |
|
70 | - * @var string $ns Namespace of the plugin |
|
71 | - * @var string $action "created", "extended", "logged_in", or "revoked" |
|
72 | - * @var string $ref (Optional) Support ticket Reference ID |
|
73 | - * } |
|
74 | - * |
|
75 | - * @return bool|WP_Error False: webhook setting not defined; True: success; WP_Error: error! |
|
76 | - */ |
|
77 | - public function maybe_send_webhook($data) |
|
78 | - { |
|
79 | - $webhook_url = $this->config->get_setting('webhook_url'); |
|
80 | - |
|
81 | - if (!$webhook_url) { |
|
82 | - return false; |
|
83 | - } |
|
84 | - |
|
85 | - if (!wp_http_validate_url($webhook_url)) { |
|
86 | - $error = new WP_Error('invalid_webhook_url', 'An invalid `webhook_url` setting was passed to the TrustedLogin Client: '.esc_attr($webhook_url)); |
|
87 | - |
|
88 | - $this->logging->log($error, __METHOD__, 'error'); |
|
89 | - |
|
90 | - return $error; |
|
91 | - } |
|
92 | - |
|
93 | - try { |
|
94 | - $posted = wp_remote_post($webhook_url, ['body' => $data]); |
|
95 | - |
|
96 | - if (is_wp_error($posted)) { |
|
97 | - $this->logging->log('An error encountered while sending a webhook to '.esc_attr($webhook_url), __METHOD__, 'error', $posted); |
|
98 | - |
|
99 | - return $posted; |
|
100 | - } |
|
101 | - |
|
102 | - $this->logging->log('Webhook was sent to '.esc_attr($webhook_url), __METHOD__, 'debug', $data); |
|
103 | - |
|
104 | - return true; |
|
105 | - } catch (Exception $exception) { |
|
106 | - $this->logging->log('A fatal error was triggered while sending a webhook to '.esc_attr($webhook_url).': '.$exception->getMessage(), __METHOD__, 'error'); |
|
107 | - |
|
108 | - return new WP_Error($exception->getCode(), $exception->getMessage()); |
|
109 | - } |
|
110 | - } |
|
111 | - |
|
112 | - /** |
|
113 | - * API Function: send the API request. |
|
114 | - * |
|
115 | - * @since 1.0.0 |
|
116 | - * |
|
117 | - * @param string $path - the path for the REST API request (no initial or trailing slash needed) |
|
118 | - * @param array $data Data passed as JSON-encoded body for |
|
119 | - * @param string $method |
|
120 | - * @param array $additional_headers - any additional headers required for auth/etc |
|
121 | - * |
|
122 | - * @return array|WP_Error wp_remote_request() response or WP_Error if something went wrong |
|
123 | - */ |
|
124 | - public function send($path, $data, $method = 'POST', $additional_headers = []) |
|
125 | - { |
|
126 | - $method = is_string($method) ? strtoupper($method) : $method; |
|
127 | - |
|
128 | - if (!is_string($method) || !in_array($method, ['POST', 'PUT', 'GET', 'HEAD', 'PUSH', 'DELETE'], true)) { |
|
129 | - $this->logging->log(sprintf('Error: Method not in allowed array list (%s)', print_r($method, true)), __METHOD__, 'critical'); |
|
130 | - |
|
131 | - return new WP_Error('invalid_method', sprintf('Error: HTTP method "%s" is not in the list of allowed methods', print_r($method, true))); |
|
132 | - } |
|
133 | - |
|
134 | - $headers = [ |
|
135 | - 'Accept' => 'application/json', |
|
136 | - 'Content-Type' => 'application/json', |
|
137 | - 'Authorization' => 'Bearer '.$this->config->get_setting('auth/api_key'), |
|
138 | - ]; |
|
139 | - |
|
140 | - if (!empty($additional_headers)) { |
|
141 | - $headers = array_merge($headers, $additional_headers); |
|
142 | - } |
|
143 | - |
|
144 | - $request_options = [ |
|
145 | - 'method' => $method, |
|
146 | - 'timeout' => 15, |
|
147 | - 'httpversion' => '1.1', |
|
148 | - 'headers' => $headers, |
|
149 | - ]; |
|
150 | - |
|
151 | - if (!empty($data) && !in_array($method, ['GET', 'HEAD'], true)) { |
|
152 | - $request_options['body'] = wp_json_encode($data); |
|
153 | - } |
|
154 | - |
|
155 | - try { |
|
156 | - $api_url = $this->build_api_url($path); |
|
157 | - |
|
158 | - $this->logging->log(sprintf('Sending to %s: %s', $api_url, print_r($request_options, true)), __METHOD__, 'debug'); |
|
159 | - |
|
160 | - $response = wp_remote_request($api_url, $request_options); |
|
161 | - } catch (Exception $exception) { |
|
162 | - $error = new WP_Error('wp_remote_request_exception', sprintf('There was an exception during the remote request: %s (%s)', $exception->getMessage(), $exception->getCode())); |
|
163 | - |
|
164 | - $this->logging->log($error, __METHOD__, 'error'); |
|
165 | - |
|
166 | - return $error; |
|
167 | - } |
|
168 | - |
|
169 | - $this->logging->log(sprintf('Response: %s', print_r($response, true)), __METHOD__, 'debug'); |
|
170 | - |
|
171 | - return $response; |
|
172 | - } |
|
173 | - |
|
174 | - /** |
|
175 | - * Builds URL to API endpoints. |
|
176 | - * |
|
177 | - * @since 1.0.0 |
|
178 | - * |
|
179 | - * @param string $endpoint Endpoint to hit on the API; example "sites" or "sites/{$site_identifier}" |
|
180 | - * |
|
181 | - * @return string |
|
182 | - */ |
|
183 | - private function build_api_url($endpoint = '') |
|
184 | - { |
|
185 | - |
|
186 | - /** |
|
187 | - * Modifies the endpoint URL for the TrustedLogin service. |
|
188 | - * |
|
189 | - * @param string $url URL to TrustedLogin API |
|
190 | - * |
|
191 | - * @internal This allows pointing requests to testing servers |
|
192 | - */ |
|
193 | - $base_url = apply_filters('trustedlogin/'.$this->config->ns().'/api_url', self::API_URL); |
|
194 | - |
|
195 | - if (is_string($endpoint)) { |
|
196 | - $url = trailingslashit($base_url).$endpoint; |
|
197 | - } else { |
|
198 | - $url = trailingslashit($base_url); |
|
199 | - } |
|
200 | - |
|
201 | - return $url; |
|
202 | - } |
|
203 | - |
|
204 | - /** |
|
205 | - * Translates response codes to more nuanced error descriptions specific to TrustedLogin. |
|
206 | - * |
|
207 | - * @param array|WP_Error $api_response Response from HTTP API |
|
208 | - * |
|
209 | - * @return int|WP_Error|null If valid response, the response code ID or null. If error, a WP_Error with a message description. |
|
210 | - */ |
|
211 | - public static function check_response_code($api_response) |
|
212 | - { |
|
213 | - if (is_wp_error($api_response)) { |
|
214 | - $response_code = $api_response->get_error_code(); |
|
215 | - } else { |
|
216 | - $response_code = wp_remote_retrieve_response_code($api_response); |
|
217 | - } |
|
218 | - |
|
219 | - switch ($response_code) { |
|
220 | - |
|
221 | - // Successful response, but no sites found. |
|
222 | - case 204: |
|
223 | - return null; |
|
224 | - |
|
225 | - case 400: |
|
226 | - case 423: |
|
227 | - return new WP_Error('unable_to_verify', esc_html__('Unable to verify Pause Mode.', 'gravityview'), $api_response); |
|
228 | - |
|
229 | - case 401: |
|
230 | - return new WP_Error('unauthenticated', esc_html__('Authentication failed.', 'gravityview'), $api_response); |
|
231 | - |
|
232 | - case 402: |
|
233 | - return new WP_Error('account_error', esc_html__('TrustedLogin account issue.', 'gravityview'), $api_response); |
|
234 | - |
|
235 | - case 403: |
|
236 | - return new WP_Error('invalid_token', esc_html__('Invalid tokens.', 'gravityview'), $api_response); |
|
237 | - |
|
238 | - // the KV store was not found, possible issue with endpoint |
|
239 | - case 404: |
|
240 | - return new WP_Error('not_found', esc_html__('The TrustedLogin vendor was not found.', 'gravityview'), $api_response); |
|
241 | - |
|
242 | - // The site is a teapot. |
|
243 | - case 418: |
|
244 | - return new WP_Error('teapot', ' |
@@ -13,7 +13,7 @@ discard block |
||
13 | 13 | namespace GravityView\TrustedLogin; |
14 | 14 | |
15 | 15 | // Exit if accessed directly |
16 | -if (!defined('ABSPATH')) { |
|
16 | +if ( ! defined( 'ABSPATH' ) ) { |
|
17 | 17 | exit; |
18 | 18 | } |
19 | 19 | |
@@ -45,7 +45,7 @@ discard block |
||
45 | 45 | /** |
46 | 46 | * SupportUser constructor. |
47 | 47 | */ |
48 | - public function __construct(Config $config, Logging $logging) |
|
48 | + public function __construct( Config $config, Logging $logging ) |
|
49 | 49 | { |
50 | 50 | $this->config = $config; |
51 | 51 | $this->logging = $logging; |
@@ -53,10 +53,10 @@ discard block |
||
53 | 53 | |
54 | 54 | public function init() |
55 | 55 | { |
56 | - add_action('trustedlogin/'.$this->config->ns().'/access/created', [$this, 'maybe_send_webhook']); |
|
57 | - add_action('trustedlogin/'.$this->config->ns().'/access/extended', [$this, 'maybe_send_webhook']); |
|
58 | - add_action('trustedlogin/'.$this->config->ns().'/access/revoked', [$this, 'maybe_send_webhook']); |
|
59 | - add_action('trustedlogin/'.$this->config->ns().'/logged_in', [$this, 'maybe_send_webhook']); |
|
56 | + add_action( 'trustedlogin/' . $this->config->ns() . '/access/created', [ $this, 'maybe_send_webhook' ] ); |
|
57 | + add_action( 'trustedlogin/' . $this->config->ns() . '/access/extended', [ $this, 'maybe_send_webhook' ] ); |
|
58 | + add_action( 'trustedlogin/' . $this->config->ns() . '/access/revoked', [ $this, 'maybe_send_webhook' ] ); |
|
59 | + add_action( 'trustedlogin/' . $this->config->ns() . '/logged_in', [ $this, 'maybe_send_webhook' ] ); |
|
60 | 60 | } |
61 | 61 | |
62 | 62 | /** |
@@ -74,38 +74,38 @@ discard block |
||
74 | 74 | * |
75 | 75 | * @return bool|WP_Error False: webhook setting not defined; True: success; WP_Error: error! |
76 | 76 | */ |
77 | - public function maybe_send_webhook($data) |
|
77 | + public function maybe_send_webhook( $data ) |
|
78 | 78 | { |
79 | - $webhook_url = $this->config->get_setting('webhook_url'); |
|
79 | + $webhook_url = $this->config->get_setting( 'webhook_url' ); |
|
80 | 80 | |
81 | - if (!$webhook_url) { |
|
81 | + if ( ! $webhook_url ) { |
|
82 | 82 | return false; |
83 | 83 | } |
84 | 84 | |
85 | - if (!wp_http_validate_url($webhook_url)) { |
|
86 | - $error = new WP_Error('invalid_webhook_url', 'An invalid `webhook_url` setting was passed to the TrustedLogin Client: '.esc_attr($webhook_url)); |
|
85 | + if ( ! wp_http_validate_url( $webhook_url ) ) { |
|
86 | + $error = new WP_Error( 'invalid_webhook_url', 'An invalid `webhook_url` setting was passed to the TrustedLogin Client: ' . esc_attr( $webhook_url ) ); |
|
87 | 87 | |
88 | - $this->logging->log($error, __METHOD__, 'error'); |
|
88 | + $this->logging->log( $error, __METHOD__, 'error' ); |
|
89 | 89 | |
90 | 90 | return $error; |
91 | 91 | } |
92 | 92 | |
93 | 93 | try { |
94 | - $posted = wp_remote_post($webhook_url, ['body' => $data]); |
|
94 | + $posted = wp_remote_post( $webhook_url, [ 'body' => $data ] ); |
|
95 | 95 | |
96 | - if (is_wp_error($posted)) { |
|
97 | - $this->logging->log('An error encountered while sending a webhook to '.esc_attr($webhook_url), __METHOD__, 'error', $posted); |
|
96 | + if ( is_wp_error( $posted ) ) { |
|
97 | + $this->logging->log( 'An error encountered while sending a webhook to ' . esc_attr( $webhook_url ), __METHOD__, 'error', $posted ); |
|
98 | 98 | |
99 | 99 | return $posted; |
100 | 100 | } |
101 | 101 | |
102 | - $this->logging->log('Webhook was sent to '.esc_attr($webhook_url), __METHOD__, 'debug', $data); |
|
102 | + $this->logging->log( 'Webhook was sent to ' . esc_attr( $webhook_url ), __METHOD__, 'debug', $data ); |
|
103 | 103 | |
104 | 104 | return true; |
105 | - } catch (Exception $exception) { |
|
106 | - $this->logging->log('A fatal error was triggered while sending a webhook to '.esc_attr($webhook_url).': '.$exception->getMessage(), __METHOD__, 'error'); |
|
105 | + } catch ( Exception $exception ) { |
|
106 | + $this->logging->log( 'A fatal error was triggered while sending a webhook to ' . esc_attr( $webhook_url ) . ': ' . $exception->getMessage(), __METHOD__, 'error' ); |
|
107 | 107 | |
108 | - return new WP_Error($exception->getCode(), $exception->getMessage()); |
|
108 | + return new WP_Error( $exception->getCode(), $exception->getMessage() ); |
|
109 | 109 | } |
110 | 110 | } |
111 | 111 | |
@@ -121,24 +121,24 @@ discard block |
||
121 | 121 | * |
122 | 122 | * @return array|WP_Error wp_remote_request() response or WP_Error if something went wrong |
123 | 123 | */ |
124 | - public function send($path, $data, $method = 'POST', $additional_headers = []) |
|
124 | + public function send( $path, $data, $method = 'POST', $additional_headers = [ ] ) |
|
125 | 125 | { |
126 | - $method = is_string($method) ? strtoupper($method) : $method; |
|
126 | + $method = is_string( $method ) ? strtoupper( $method ) : $method; |
|
127 | 127 | |
128 | - if (!is_string($method) || !in_array($method, ['POST', 'PUT', 'GET', 'HEAD', 'PUSH', 'DELETE'], true)) { |
|
129 | - $this->logging->log(sprintf('Error: Method not in allowed array list (%s)', print_r($method, true)), __METHOD__, 'critical'); |
|
128 | + if ( ! is_string( $method ) || ! in_array( $method, [ 'POST', 'PUT', 'GET', 'HEAD', 'PUSH', 'DELETE' ], true ) ) { |
|
129 | + $this->logging->log( sprintf( 'Error: Method not in allowed array list (%s)', print_r( $method, true ) ), __METHOD__, 'critical' ); |
|
130 | 130 | |
131 | - return new WP_Error('invalid_method', sprintf('Error: HTTP method "%s" is not in the list of allowed methods', print_r($method, true))); |
|
131 | + return new WP_Error( 'invalid_method', sprintf( 'Error: HTTP method "%s" is not in the list of allowed methods', print_r( $method, true ) ) ); |
|
132 | 132 | } |
133 | 133 | |
134 | 134 | $headers = [ |
135 | 135 | 'Accept' => 'application/json', |
136 | 136 | 'Content-Type' => 'application/json', |
137 | - 'Authorization' => 'Bearer '.$this->config->get_setting('auth/api_key'), |
|
137 | + 'Authorization' => 'Bearer ' . $this->config->get_setting( 'auth/api_key' ), |
|
138 | 138 | ]; |
139 | 139 | |
140 | - if (!empty($additional_headers)) { |
|
141 | - $headers = array_merge($headers, $additional_headers); |
|
140 | + if ( ! empty( $additional_headers ) ) { |
|
141 | + $headers = array_merge( $headers, $additional_headers ); |
|
142 | 142 | } |
143 | 143 | |
144 | 144 | $request_options = [ |
@@ -148,25 +148,25 @@ discard block |
||
148 | 148 | 'headers' => $headers, |
149 | 149 | ]; |
150 | 150 | |
151 | - if (!empty($data) && !in_array($method, ['GET', 'HEAD'], true)) { |
|
152 | - $request_options['body'] = wp_json_encode($data); |
|
151 | + if ( ! empty( $data ) && ! in_array( $method, [ 'GET', 'HEAD' ], true ) ) { |
|
152 | + $request_options[ 'body' ] = wp_json_encode( $data ); |
|
153 | 153 | } |
154 | 154 | |
155 | 155 | try { |
156 | - $api_url = $this->build_api_url($path); |
|
156 | + $api_url = $this->build_api_url( $path ); |
|
157 | 157 | |
158 | - $this->logging->log(sprintf('Sending to %s: %s', $api_url, print_r($request_options, true)), __METHOD__, 'debug'); |
|
158 | + $this->logging->log( sprintf( 'Sending to %s: %s', $api_url, print_r( $request_options, true ) ), __METHOD__, 'debug' ); |
|
159 | 159 | |
160 | - $response = wp_remote_request($api_url, $request_options); |
|
161 | - } catch (Exception $exception) { |
|
162 | - $error = new WP_Error('wp_remote_request_exception', sprintf('There was an exception during the remote request: %s (%s)', $exception->getMessage(), $exception->getCode())); |
|
160 | + $response = wp_remote_request( $api_url, $request_options ); |
|
161 | + } catch ( Exception $exception ) { |
|
162 | + $error = new WP_Error( 'wp_remote_request_exception', sprintf( 'There was an exception during the remote request: %s (%s)', $exception->getMessage(), $exception->getCode() ) ); |
|
163 | 163 | |
164 | - $this->logging->log($error, __METHOD__, 'error'); |
|
164 | + $this->logging->log( $error, __METHOD__, 'error' ); |
|
165 | 165 | |
166 | 166 | return $error; |
167 | 167 | } |
168 | 168 | |
169 | - $this->logging->log(sprintf('Response: %s', print_r($response, true)), __METHOD__, 'debug'); |
|
169 | + $this->logging->log( sprintf( 'Response: %s', print_r( $response, true ) ), __METHOD__, 'debug' ); |
|
170 | 170 | |
171 | 171 | return $response; |
172 | 172 | } |
@@ -180,7 +180,7 @@ discard block |
||
180 | 180 | * |
181 | 181 | * @return string |
182 | 182 | */ |
183 | - private function build_api_url($endpoint = '') |
|
183 | + private function build_api_url( $endpoint = '' ) |
|
184 | 184 | { |
185 | 185 | |
186 | 186 | /** |
@@ -190,12 +190,12 @@ discard block |
||
190 | 190 | * |
191 | 191 | * @internal This allows pointing requests to testing servers |
192 | 192 | */ |
193 | - $base_url = apply_filters('trustedlogin/'.$this->config->ns().'/api_url', self::API_URL); |
|
193 | + $base_url = apply_filters( 'trustedlogin/' . $this->config->ns() . '/api_url', self::API_URL ); |
|
194 | 194 | |
195 | - if (is_string($endpoint)) { |
|
196 | - $url = trailingslashit($base_url).$endpoint; |
|
195 | + if ( is_string( $endpoint ) ) { |
|
196 | + $url = trailingslashit( $base_url ) . $endpoint; |
|
197 | 197 | } else { |
198 | - $url = trailingslashit($base_url); |
|
198 | + $url = trailingslashit( $base_url ); |
|
199 | 199 | } |
200 | 200 | |
201 | 201 | return $url; |
@@ -208,15 +208,15 @@ discard block |
||
208 | 208 | * |
209 | 209 | * @return int|WP_Error|null If valid response, the response code ID or null. If error, a WP_Error with a message description. |
210 | 210 | */ |
211 | - public static function check_response_code($api_response) |
|
211 | + public static function check_response_code( $api_response ) |
|
212 | 212 | { |
213 | - if (is_wp_error($api_response)) { |
|
213 | + if ( is_wp_error( $api_response ) ) { |
|
214 | 214 | $response_code = $api_response->get_error_code(); |
215 | 215 | } else { |
216 | - $response_code = wp_remote_retrieve_response_code($api_response); |
|
216 | + $response_code = wp_remote_retrieve_response_code( $api_response ); |
|
217 | 217 | } |
218 | 218 | |
219 | - switch ($response_code) { |
|
219 | + switch ( $response_code ) { |
|
220 | 220 | |
221 | 221 | // Successful response, but no sites found. |
222 | 222 | case 204: |
@@ -224,43 +224,43 @@ discard block |
||
224 | 224 | |
225 | 225 | case 400: |
226 | 226 | case 423: |
227 | - return new WP_Error('unable_to_verify', esc_html__('Unable to verify Pause Mode.', 'gravityview'), $api_response); |
|
227 | + return new WP_Error( 'unable_to_verify', esc_html__( 'Unable to verify Pause Mode.', 'gravityview' ), $api_response ); |
|
228 | 228 | |
229 | 229 | case 401: |
230 | - return new WP_Error('unauthenticated', esc_html__('Authentication failed.', 'gravityview'), $api_response); |
|
230 | + return new WP_Error( 'unauthenticated', esc_html__( 'Authentication failed.', 'gravityview' ), $api_response ); |
|
231 | 231 | |
232 | 232 | case 402: |
233 | - return new WP_Error('account_error', esc_html__('TrustedLogin account issue.', 'gravityview'), $api_response); |
|
233 | + return new WP_Error( 'account_error', esc_html__( 'TrustedLogin account issue.', 'gravityview' ), $api_response ); |
|
234 | 234 | |
235 | 235 | case 403: |
236 | - return new WP_Error('invalid_token', esc_html__('Invalid tokens.', 'gravityview'), $api_response); |
|
236 | + return new WP_Error( 'invalid_token', esc_html__( 'Invalid tokens.', 'gravityview' ), $api_response ); |
|
237 | 237 | |
238 | 238 | // the KV store was not found, possible issue with endpoint |
239 | 239 | case 404: |
240 | - return new WP_Error('not_found', esc_html__('The TrustedLogin vendor was not found.', 'gravityview'), $api_response); |
|
240 | + return new WP_Error( 'not_found', esc_html__( 'The TrustedLogin vendor was not found.', 'gravityview' ), $api_response ); |
|
241 | 241 | |
242 | 242 | // The site is a teapot. |
243 | 243 | case 418: |
244 | - return new WP_Error('teapot', ' |
@@ -23,8 +23,7 @@ discard block |
||
23 | 23 | /** |
24 | 24 | * The TrustedLogin all-in-one drop-in class. |
25 | 25 | */ |
26 | -final class Remote |
|
27 | -{ |
|
26 | +final class Remote { |
|
28 | 27 | /** |
29 | 28 | * @var string The API url for the TrustedLogin SaaS Platform (with trailing slash) |
30 | 29 | * |
@@ -45,14 +44,12 @@ discard block |
||
45 | 44 | /** |
46 | 45 | * SupportUser constructor. |
47 | 46 | */ |
48 | - public function __construct(Config $config, Logging $logging) |
|
49 | - { |
|
47 | + public function __construct(Config $config, Logging $logging) { |
|
50 | 48 | $this->config = $config; |
51 | 49 | $this->logging = $logging; |
52 | 50 | } |
53 | 51 | |
54 | - public function init() |
|
55 | - { |
|
52 | + public function init() { |
|
56 | 53 | add_action('trustedlogin/'.$this->config->ns().'/access/created', [$this, 'maybe_send_webhook']); |
57 | 54 | add_action('trustedlogin/'.$this->config->ns().'/access/extended', [$this, 'maybe_send_webhook']); |
58 | 55 | add_action('trustedlogin/'.$this->config->ns().'/access/revoked', [$this, 'maybe_send_webhook']); |
@@ -74,8 +71,7 @@ discard block |
||
74 | 71 | * |
75 | 72 | * @return bool|WP_Error False: webhook setting not defined; True: success; WP_Error: error! |
76 | 73 | */ |
77 | - public function maybe_send_webhook($data) |
|
78 | - { |
|
74 | + public function maybe_send_webhook($data) { |
|
79 | 75 | $webhook_url = $this->config->get_setting('webhook_url'); |
80 | 76 | |
81 | 77 | if (!$webhook_url) { |
@@ -121,8 +117,7 @@ discard block |
||
121 | 117 | * |
122 | 118 | * @return array|WP_Error wp_remote_request() response or WP_Error if something went wrong |
123 | 119 | */ |
124 | - public function send($path, $data, $method = 'POST', $additional_headers = []) |
|
125 | - { |
|
120 | + public function send($path, $data, $method = 'POST', $additional_headers = []) { |
|
126 | 121 | $method = is_string($method) ? strtoupper($method) : $method; |
127 | 122 | |
128 | 123 | if (!is_string($method) || !in_array($method, ['POST', 'PUT', 'GET', 'HEAD', 'PUSH', 'DELETE'], true)) { |
@@ -180,8 +175,7 @@ discard block |
||
180 | 175 | * |
181 | 176 | * @return string |
182 | 177 | */ |
183 | - private function build_api_url($endpoint = '') |
|
184 | - { |
|
178 | + private function build_api_url($endpoint = '') { |
|
185 | 179 | |
186 | 180 | /** |
187 | 181 | * Modifies the endpoint URL for the TrustedLogin service. |
@@ -208,8 +202,7 @@ discard block |
||
208 | 202 | * |
209 | 203 | * @return int|WP_Error|null If valid response, the response code ID or null. If error, a WP_Error with a message description. |
210 | 204 | */ |
211 | - public static function check_response_code($api_response) |
|
212 | - { |
|
205 | + public static function check_response_code($api_response) { |
|
213 | 206 | if (is_wp_error($api_response)) { |
214 | 207 | $response_code = $api_response->get_error_code(); |
215 | 208 | } else { |
@@ -274,8 +267,7 @@ discard block |
||
274 | 267 | * |
275 | 268 | * @return array|WP_Error|null If successful response, returns array of JSON data. If failed, returns WP_Error. If |
276 | 269 | */ |
277 | - public function handle_response($api_response, $required_keys = []) |
|
278 | - { |
|
270 | + public function handle_response($api_response, $required_keys = []) { |
|
279 | 271 | $response_code = self::check_response_code($api_response); |
280 | 272 | |
281 | 273 | // Null means a successful response, but does not return any body content (204). We can return early. |
@@ -16,346 +16,346 @@ |
||
16 | 16 | |
17 | 17 | final class SecurityChecks |
18 | 18 | { |
19 | - /** |
|
20 | - * @var Logging |
|
21 | - */ |
|
22 | - private $logging; |
|
23 | - |
|
24 | - /** |
|
25 | - * @var Config |
|
26 | - */ |
|
27 | - private $config; |
|
28 | - |
|
29 | - /** |
|
30 | - * @var string The transient slug used for storing used accesskeys. |
|
31 | - */ |
|
32 | - private $used_accesskey_transient; |
|
33 | - |
|
34 | - /** |
|
35 | - * @var string The transient slug used for noting if we're temporarily blocking access. |
|
36 | - */ |
|
37 | - private $in_lockdown_transient; |
|
38 | - |
|
39 | - /** |
|
40 | - * @var int The number of incorrect access keys that should trigger an anomaly alert. |
|
41 | - */ |
|
42 | - const ACCESSKEY_LIMIT_COUNT = 3; |
|
43 | - |
|
44 | - /** |
|
45 | - * @var int The number of seconds we should keep incorrect access keys stored for. |
|
46 | - */ |
|
47 | - const ACCESSKEY_LIMIT_EXPIRY = 36000; // 10 * MINUTE_IN_SECONDS; |
|
48 | - |
|
49 | - /** |
|
50 | - * @var int The number of seconds should block trustedlogin auto-logins for. |
|
51 | - */ |
|
52 | - const LOCKDOWN_EXPIRY = 72000; // 20 * MINUTE_IN_SECONDS; |
|
53 | - |
|
54 | - /** |
|
55 | - * @var string TrustedLogin endpoint to notify brute-force activity |
|
56 | - */ |
|
57 | - const BRUTE_FORCE_ENDPOINT = 'report-brute-force'; |
|
58 | - |
|
59 | - /** |
|
60 | - * @var string TrustedLogin endpoint to verify valid support activity |
|
61 | - */ |
|
62 | - const VERIFY_SUPPORT_AGENT_ENDPOINT = 'verify-identifier'; |
|
63 | - |
|
64 | - public function __construct(Config $config, Logging $logging) |
|
65 | - { |
|
66 | - $this->logging = $logging; |
|
67 | - $this->config = $config; |
|
68 | - |
|
69 | - $this->used_accesskey_transient = 'tl-'.$this->config->ns().'-used_accesskeys'; |
|
70 | - $this->in_lockdown_transient = 'tl-'.$this->config->ns().'-in_lockdown'; |
|
71 | - } |
|
72 | - |
|
73 | - /** |
|
74 | - * Verifies that a provided user identifier is still valid. |
|
75 | - * |
|
76 | - * Multiple security checks are performed, including brute-force and known-attacker-list checks |
|
77 | - * |
|
78 | - * @param string $passed_user_identifier The identifier provided via {@see SupportUser::maybe_login()} |
|
79 | - * |
|
80 | - * @return true|WP_Error True if identifier passes checks. WP_Error if not. |
|
81 | - */ |
|
82 | - public function verify($passed_user_identifier = '') |
|
83 | - { |
|
84 | - $user_identifier = $passed_user_identifier; |
|
85 | - |
|
86 | - if ($this->in_lockdown()) { |
|
87 | - $this->logging->log('Site is in lockdown mode, aborting login.', __METHOD__, 'error'); |
|
88 | - |
|
89 | - return new WP_Error('in_lockdown', __('TrustedLogin temporarily disabled.', 'gravityview')); |
|
90 | - } |
|
91 | - |
|
92 | - // When passed in the endpoint URL, the unique ID will be the raw value, not the hash. |
|
93 | - if (strlen($passed_user_identifier) > 32) { |
|
94 | - $user_identifier = Encryption::hash($passed_user_identifier); |
|
95 | - } |
|
96 | - |
|
97 | - $brute_force = $this->check_brute_force($user_identifier); |
|
98 | - |
|
99 | - if (is_wp_error($brute_force)) { |
|
100 | - $this->do_lockdown(); |
|
101 | - |
|
102 | - return $brute_force; |
|
103 | - } |
|
104 | - |
|
105 | - $SupportUser = new SupportUser($this->config, $this->logging); |
|
106 | - |
|
107 | - $secret_id = $SupportUser->get_secret_id($user_identifier); |
|
108 | - |
|
109 | - $approved = $this->check_approved_identifier($secret_id); |
|
110 | - |
|
111 | - // Don't lock-down the site, since there could have been errors related to remote validation |
|
112 | - if (is_wp_error($approved)) { |
|
113 | - $this->logging->log( |
|
114 | - sprintf( |
|
115 | - __('There was an issue verifying the user identifier with TrustedLogin, aborting login. (%s)', 'gravityview'), |
|
116 | - $approved->get_error_message() |
|
117 | - ), |
|
118 | - __METHOD__, |
|
119 | - 'error' |
|
120 | - ); |
|
121 | - |
|
122 | - return $approved; |
|
123 | - } |
|
124 | - |
|
125 | - return true; |
|
126 | - } |
|
127 | - |
|
128 | - /** |
|
129 | - * Detects if this identifier indicates that the site's access keys may be under a brute force attack. |
|
130 | - * |
|
131 | - * @param string $identifier The identifier provided via {@see Endpoint::maybe_login_support()} |
|
132 | - * |
|
133 | - * @return true|WP_Error WP_Error if an anomaly was detected and site may be under attack. Else true. |
|
134 | - */ |
|
135 | - private function check_brute_force($identifier) |
|
136 | - { |
|
137 | - if ($this->in_local_development()) { |
|
138 | - return true; |
|
139 | - } |
|
140 | - |
|
141 | - $used_accesskeys = $this->maybe_add_used_accesskey($identifier); |
|
142 | - |
|
143 | - // Is the number of attempted accesses below the lockdown limit? |
|
144 | - if (count($used_accesskeys) >= self::ACCESSKEY_LIMIT_COUNT) { |
|
145 | - $this->logging->log( |
|
146 | - 'Potential Brute Force attack detected with identifier: '.esc_attr($identifier), |
|
147 | - __METHOD__, |
|
148 | - 'notice' |
|
149 | - ); |
|
150 | - |
|
151 | - return new WP_Error('brute_force_detected', 'Login aborted due to potential brute force detection.'); |
|
152 | - } |
|
153 | - |
|
154 | - return true; |
|
155 | - } |
|
156 | - |
|
157 | - /** |
|
158 | - * @param string $user_identifier |
|
159 | - * |
|
160 | - * @return mixed |
|
161 | - */ |
|
162 | - private function maybe_add_used_accesskey($user_identifier = '') |
|
163 | - { |
|
164 | - $used_accesskeys = (array) get_site_transient($this->used_accesskey_transient); |
|
165 | - |
|
166 | - // This is a new access key |
|
167 | - if (!in_array($user_identifier, $used_accesskeys, true)) { |
|
168 | - $used_accesskeys[] = $user_identifier; |
|
169 | - |
|
170 | - $transient_set = set_site_transient($this->used_accesskey_transient, $used_accesskeys, self::ACCESSKEY_LIMIT_EXPIRY); |
|
171 | - |
|
172 | - if (!$transient_set) { |
|
173 | - $this->logging->log('Used access key transient not properly set/updated.', __METHOD__, 'error'); |
|
174 | - } |
|
175 | - } |
|
176 | - |
|
177 | - return $used_accesskeys; |
|
178 | - } |
|
179 | - |
|
180 | - /** |
|
181 | - * Returns the IP address of the requester. |
|
182 | - * |
|
183 | - * @return null|string Returns null if REMOTE_ADDR isn't set, string IP address otherwise. |
|
184 | - */ |
|
185 | - private function get_ip() |
|
186 | - { |
|
187 | - if (!isset($_SERVER['REMOTE_ADDR'])) { |
|
188 | - return null; |
|
189 | - } |
|
190 | - |
|
191 | - $ip = wp_unslash($_SERVER['REMOTE_ADDR']); |
|
192 | - |
|
193 | - $ip = trim($ip); |
|
194 | - |
|
195 | - if (!defined('TL_DOING_TESTS')) { |
|
196 | - $ip = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE); |
|
197 | - } |
|
198 | - |
|
199 | - return (string) $ip; |
|
200 | - } |
|
201 | - |
|
202 | - /** |
|
203 | - * Makes double-y sure the TrustedLogin Server approves this support-agent login. |
|
204 | - * |
|
205 | - * This function sends server variables to the TrustedLogin server to help prevent a number of attack vectors. |
|
206 | - * It is *only* ever triggered as part of the auto-login sequence. |
|
207 | - * The session data synced will only ever be from authorized support teams, or potential attackers. |
|
208 | - * |
|
209 | - * @param string $secret_id The secret ID for the site. |
|
210 | - * |
|
211 | - * @return true|WP_Error True: the TrustedLogin service was reached and the login remains valid. WP_Error: The service wasn't reachable or the service responded that the secret ID wasn't valid. |
|
212 | - */ |
|
213 | - private function check_approved_identifier($secret_id) |
|
214 | - { |
|
215 | - |
|
216 | - /** |
|
217 | - * This array contains information from the Vendor's support agent |
|
218 | - * as a means of protecting against potential breaches. |
|
219 | - * |
|
220 | - * No site user/visitor/admin data is sent back to TrustedLogin server. |
|
221 | - */ |
|
222 | - $body = [ |
|
223 | - 'timestamp' => time(), |
|
224 | - 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? substr($_SERVER['HTTP_USER_AGENT'], 0, 255) : '', |
|
225 | - 'user_ip' => $this->get_ip(), |
|
226 | - 'site_url' => get_site_url(), |
|
227 | - ]; |
|
228 | - |
|
229 | - $remote = new Remote($this->config, $this->logging); |
|
230 | - |
|
231 | - $api_response = $remote->send('sites/'.$secret_id.'/'.self::VERIFY_SUPPORT_AGENT_ENDPOINT, $body, 'POST'); |
|
232 | - |
|
233 | - if (is_wp_error($api_response)) { |
|
234 | - return $api_response; |
|
235 | - } |
|
236 | - |
|
237 | - $response = $remote->handle_response($api_response); |
|
238 | - |
|
239 | - if (is_wp_error($response)) { |
|
240 | - return $response; |
|
241 | - } |
|
242 | - |
|
243 | - return true; |
|
244 | - } |
|
245 | - |
|
246 | - /** |
|
247 | - * Notifies the TrustedLogin server that a site may be under a possible brute-force attack. |
|
248 | - * |
|
249 | - * @since 1.0.0 |
|
250 | - * |
|
251 | - * @return true|WP_Error If the notification was sent, returns true, otherwise WP_Error on issue. |
|
252 | - */ |
|
253 | - private function report_lockdown() |
|
254 | - { |
|
255 | - |
|
256 | - /** |
|
257 | - * This array contains identifiable information of either a malicious actor |
|
258 | - * or the Vendor's support agent who is triggering the alert. |
|
259 | - * |
|
260 | - * No site user/visitor/admin data is sent back to TrustedLogin server. |
|
261 | - */ |
|
262 | - $body = [ |
|
263 | - 'timestamp' => time(), |
|
264 | - 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? substr($_SERVER['HTTP_USER_AGENT'], 0, 255) : '', |
|
265 | - 'user_ip' => $this->get_ip(), |
|
266 | - 'site_url' => get_site_url(), |
|
267 | - ]; |
|
268 | - |
|
269 | - $remote = new Remote($this->config, $this->logging); |
|
270 | - $api_response = $remote->send(self::BRUTE_FORCE_ENDPOINT, $body, 'POST'); |
|
271 | - |
|
272 | - if (is_wp_error($api_response)) { |
|
273 | - return $api_response; |
|
274 | - } |
|
275 | - |
|
276 | - $response = $remote->handle_response($api_response); |
|
277 | - |
|
278 | - if (is_wp_error($response)) { |
|
279 | - return $response; |
|
280 | - } |
|
281 | - |
|
282 | - return true; |
|
283 | - } |
|
284 | - |
|
285 | - /** |
|
286 | - * Locks down the site to new access by TrustedLogin identifiers, reports lockdown to TrustedLogin. |
|
287 | - */ |
|
288 | - private function do_lockdown() |
|
289 | - { |
|
290 | - $this->logging->log('Brute force is detected; starting lockdown.', __METHOD__, 'emergency'); |
|
291 | - |
|
292 | - $transient_set = set_site_transient($this->in_lockdown_transient, time(), self::LOCKDOWN_EXPIRY); |
|
293 | - |
|
294 | - if (!$transient_set) { |
|
295 | - $this->logging->log('Could not set the "in lockdown" transient.', __METHOD__, 'alert'); |
|
296 | - } |
|
297 | - |
|
298 | - $notified = $this->report_lockdown(); |
|
299 | - |
|
300 | - if (is_wp_error($notified)) { |
|
301 | - $this->logging->log(sprintf('Could not notify TrustedLogin (%s)', $notified->get_error_message()), __METHOD__, 'error'); |
|
302 | - } |
|
303 | - |
|
304 | - /** |
|
305 | - * Runs after the site is locked down to access from the Vendor. |
|
306 | - */ |
|
307 | - do_action('trustedlogin/'.$this->config->ns().'/lockdown/after'); |
|
308 | - } |
|
309 | - |
|
310 | - /** |
|
311 | - * Is this site in local development mode? |
|
312 | - * |
|
313 | - * @uses \wp_get_environment_type() If available, used to fetch site's development environment |
|
314 | - * |
|
315 | - * @see https://developer.wordpress.org/reference/functions/wp_get_environment_type/ |
|
316 | - * |
|
317 | - * To bypass lockdown checks, set a WordPress environment to `local` or `development`. Alternately, you may |
|
318 | - * add a constant to the site's wp-config.php file formatted as `TRUSTEDLOGIN_TESTING_{EXAMPLE}` where |
|
319 | - * `{EXAMPLE}` is replaced with the project's upper-cased namespace. |
|
320 | - * |
|
321 | - * @return bool True: site is in local or development environment. False: site is live. |
|
322 | - */ |
|
323 | - private function in_local_development() |
|
324 | - { |
|
325 | - $constant_name = 'TRUSTEDLOGIN_TESTING_'.strtoupper($this->config->ns()); |
|
326 | - |
|
327 | - if (defined($constant_name) && constant($constant_name)) { |
|
328 | - return true; |
|
329 | - } |
|
330 | - |
|
331 | - if (!function_exists('wp_get_environment_type')) { |
|
332 | - return false; |
|
333 | - } |
|
334 | - |
|
335 | - switch (wp_get_environment_type()) { |
|
336 | - case 'local': |
|
337 | - case 'development': |
|
338 | - return true; |
|
339 | - break; |
|
340 | - case 'staging': |
|
341 | - case 'production': |
|
342 | - default: |
|
343 | - } |
|
344 | - |
|
345 | - return false; |
|
346 | - } |
|
347 | - |
|
348 | - /** |
|
349 | - * Checks if TrustedLogin is currently in lockdown. |
|
350 | - * |
|
351 | - * @return int|false Int: in lockdown. The value returned is the timestamp when lockdown ends. False: not in lockdown, or overridden by a constant. |
|
352 | - */ |
|
353 | - public function in_lockdown() |
|
354 | - { |
|
355 | - if ($this->in_local_development()) { |
|
356 | - return false; |
|
357 | - } |
|
358 | - |
|
359 | - return get_site_transient($this->in_lockdown_transient); |
|
360 | - } |
|
19 | + /** |
|
20 | + * @var Logging |
|
21 | + */ |
|
22 | + private $logging; |
|
23 | + |
|
24 | + /** |
|
25 | + * @var Config |
|
26 | + */ |
|
27 | + private $config; |
|
28 | + |
|
29 | + /** |
|
30 | + * @var string The transient slug used for storing used accesskeys. |
|
31 | + */ |
|
32 | + private $used_accesskey_transient; |
|
33 | + |
|
34 | + /** |
|
35 | + * @var string The transient slug used for noting if we're temporarily blocking access. |
|
36 | + */ |
|
37 | + private $in_lockdown_transient; |
|
38 | + |
|
39 | + /** |
|
40 | + * @var int The number of incorrect access keys that should trigger an anomaly alert. |
|
41 | + */ |
|
42 | + const ACCESSKEY_LIMIT_COUNT = 3; |
|
43 | + |
|
44 | + /** |
|
45 | + * @var int The number of seconds we should keep incorrect access keys stored for. |
|
46 | + */ |
|
47 | + const ACCESSKEY_LIMIT_EXPIRY = 36000; // 10 * MINUTE_IN_SECONDS; |
|
48 | + |
|
49 | + /** |
|
50 | + * @var int The number of seconds should block trustedlogin auto-logins for. |
|
51 | + */ |
|
52 | + const LOCKDOWN_EXPIRY = 72000; // 20 * MINUTE_IN_SECONDS; |
|
53 | + |
|
54 | + /** |
|
55 | + * @var string TrustedLogin endpoint to notify brute-force activity |
|
56 | + */ |
|
57 | + const BRUTE_FORCE_ENDPOINT = 'report-brute-force'; |
|
58 | + |
|
59 | + /** |
|
60 | + * @var string TrustedLogin endpoint to verify valid support activity |
|
61 | + */ |
|
62 | + const VERIFY_SUPPORT_AGENT_ENDPOINT = 'verify-identifier'; |
|
63 | + |
|
64 | + public function __construct(Config $config, Logging $logging) |
|
65 | + { |
|
66 | + $this->logging = $logging; |
|
67 | + $this->config = $config; |
|
68 | + |
|
69 | + $this->used_accesskey_transient = 'tl-'.$this->config->ns().'-used_accesskeys'; |
|
70 | + $this->in_lockdown_transient = 'tl-'.$this->config->ns().'-in_lockdown'; |
|
71 | + } |
|
72 | + |
|
73 | + /** |
|
74 | + * Verifies that a provided user identifier is still valid. |
|
75 | + * |
|
76 | + * Multiple security checks are performed, including brute-force and known-attacker-list checks |
|
77 | + * |
|
78 | + * @param string $passed_user_identifier The identifier provided via {@see SupportUser::maybe_login()} |
|
79 | + * |
|
80 | + * @return true|WP_Error True if identifier passes checks. WP_Error if not. |
|
81 | + */ |
|
82 | + public function verify($passed_user_identifier = '') |
|
83 | + { |
|
84 | + $user_identifier = $passed_user_identifier; |
|
85 | + |
|
86 | + if ($this->in_lockdown()) { |
|
87 | + $this->logging->log('Site is in lockdown mode, aborting login.', __METHOD__, 'error'); |
|
88 | + |
|
89 | + return new WP_Error('in_lockdown', __('TrustedLogin temporarily disabled.', 'gravityview')); |
|
90 | + } |
|
91 | + |
|
92 | + // When passed in the endpoint URL, the unique ID will be the raw value, not the hash. |
|
93 | + if (strlen($passed_user_identifier) > 32) { |
|
94 | + $user_identifier = Encryption::hash($passed_user_identifier); |
|
95 | + } |
|
96 | + |
|
97 | + $brute_force = $this->check_brute_force($user_identifier); |
|
98 | + |
|
99 | + if (is_wp_error($brute_force)) { |
|
100 | + $this->do_lockdown(); |
|
101 | + |
|
102 | + return $brute_force; |
|
103 | + } |
|
104 | + |
|
105 | + $SupportUser = new SupportUser($this->config, $this->logging); |
|
106 | + |
|
107 | + $secret_id = $SupportUser->get_secret_id($user_identifier); |
|
108 | + |
|
109 | + $approved = $this->check_approved_identifier($secret_id); |
|
110 | + |
|
111 | + // Don't lock-down the site, since there could have been errors related to remote validation |
|
112 | + if (is_wp_error($approved)) { |
|
113 | + $this->logging->log( |
|
114 | + sprintf( |
|
115 | + __('There was an issue verifying the user identifier with TrustedLogin, aborting login. (%s)', 'gravityview'), |
|
116 | + $approved->get_error_message() |
|
117 | + ), |
|
118 | + __METHOD__, |
|
119 | + 'error' |
|
120 | + ); |
|
121 | + |
|
122 | + return $approved; |
|
123 | + } |
|
124 | + |
|
125 | + return true; |
|
126 | + } |
|
127 | + |
|
128 | + /** |
|
129 | + * Detects if this identifier indicates that the site's access keys may be under a brute force attack. |
|
130 | + * |
|
131 | + * @param string $identifier The identifier provided via {@see Endpoint::maybe_login_support()} |
|
132 | + * |
|
133 | + * @return true|WP_Error WP_Error if an anomaly was detected and site may be under attack. Else true. |
|
134 | + */ |
|
135 | + private function check_brute_force($identifier) |
|
136 | + { |
|
137 | + if ($this->in_local_development()) { |
|
138 | + return true; |
|
139 | + } |
|
140 | + |
|
141 | + $used_accesskeys = $this->maybe_add_used_accesskey($identifier); |
|
142 | + |
|
143 | + // Is the number of attempted accesses below the lockdown limit? |
|
144 | + if (count($used_accesskeys) >= self::ACCESSKEY_LIMIT_COUNT) { |
|
145 | + $this->logging->log( |
|
146 | + 'Potential Brute Force attack detected with identifier: '.esc_attr($identifier), |
|
147 | + __METHOD__, |
|
148 | + 'notice' |
|
149 | + ); |
|
150 | + |
|
151 | + return new WP_Error('brute_force_detected', 'Login aborted due to potential brute force detection.'); |
|
152 | + } |
|
153 | + |
|
154 | + return true; |
|
155 | + } |
|
156 | + |
|
157 | + /** |
|
158 | + * @param string $user_identifier |
|
159 | + * |
|
160 | + * @return mixed |
|
161 | + */ |
|
162 | + private function maybe_add_used_accesskey($user_identifier = '') |
|
163 | + { |
|
164 | + $used_accesskeys = (array) get_site_transient($this->used_accesskey_transient); |
|
165 | + |
|
166 | + // This is a new access key |
|
167 | + if (!in_array($user_identifier, $used_accesskeys, true)) { |
|
168 | + $used_accesskeys[] = $user_identifier; |
|
169 | + |
|
170 | + $transient_set = set_site_transient($this->used_accesskey_transient, $used_accesskeys, self::ACCESSKEY_LIMIT_EXPIRY); |
|
171 | + |
|
172 | + if (!$transient_set) { |
|
173 | + $this->logging->log('Used access key transient not properly set/updated.', __METHOD__, 'error'); |
|
174 | + } |
|
175 | + } |
|
176 | + |
|
177 | + return $used_accesskeys; |
|
178 | + } |
|
179 | + |
|
180 | + /** |
|
181 | + * Returns the IP address of the requester. |
|
182 | + * |
|
183 | + * @return null|string Returns null if REMOTE_ADDR isn't set, string IP address otherwise. |
|
184 | + */ |
|
185 | + private function get_ip() |
|
186 | + { |
|
187 | + if (!isset($_SERVER['REMOTE_ADDR'])) { |
|
188 | + return null; |
|
189 | + } |
|
190 | + |
|
191 | + $ip = wp_unslash($_SERVER['REMOTE_ADDR']); |
|
192 | + |
|
193 | + $ip = trim($ip); |
|
194 | + |
|
195 | + if (!defined('TL_DOING_TESTS')) { |
|
196 | + $ip = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE); |
|
197 | + } |
|
198 | + |
|
199 | + return (string) $ip; |
|
200 | + } |
|
201 | + |
|
202 | + /** |
|
203 | + * Makes double-y sure the TrustedLogin Server approves this support-agent login. |
|
204 | + * |
|
205 | + * This function sends server variables to the TrustedLogin server to help prevent a number of attack vectors. |
|
206 | + * It is *only* ever triggered as part of the auto-login sequence. |
|
207 | + * The session data synced will only ever be from authorized support teams, or potential attackers. |
|
208 | + * |
|
209 | + * @param string $secret_id The secret ID for the site. |
|
210 | + * |
|
211 | + * @return true|WP_Error True: the TrustedLogin service was reached and the login remains valid. WP_Error: The service wasn't reachable or the service responded that the secret ID wasn't valid. |
|
212 | + */ |
|
213 | + private function check_approved_identifier($secret_id) |
|
214 | + { |
|
215 | + |
|
216 | + /** |
|
217 | + * This array contains information from the Vendor's support agent |
|
218 | + * as a means of protecting against potential breaches. |
|
219 | + * |
|
220 | + * No site user/visitor/admin data is sent back to TrustedLogin server. |
|
221 | + */ |
|
222 | + $body = [ |
|
223 | + 'timestamp' => time(), |
|
224 | + 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? substr($_SERVER['HTTP_USER_AGENT'], 0, 255) : '', |
|
225 | + 'user_ip' => $this->get_ip(), |
|
226 | + 'site_url' => get_site_url(), |
|
227 | + ]; |
|
228 | + |
|
229 | + $remote = new Remote($this->config, $this->logging); |
|
230 | + |
|
231 | + $api_response = $remote->send('sites/'.$secret_id.'/'.self::VERIFY_SUPPORT_AGENT_ENDPOINT, $body, 'POST'); |
|
232 | + |
|
233 | + if (is_wp_error($api_response)) { |
|
234 | + return $api_response; |
|
235 | + } |
|
236 | + |
|
237 | + $response = $remote->handle_response($api_response); |
|
238 | + |
|
239 | + if (is_wp_error($response)) { |
|
240 | + return $response; |
|
241 | + } |
|
242 | + |
|
243 | + return true; |
|
244 | + } |
|
245 | + |
|
246 | + /** |
|
247 | + * Notifies the TrustedLogin server that a site may be under a possible brute-force attack. |
|
248 | + * |
|
249 | + * @since 1.0.0 |
|
250 | + * |
|
251 | + * @return true|WP_Error If the notification was sent, returns true, otherwise WP_Error on issue. |
|
252 | + */ |
|
253 | + private function report_lockdown() |
|
254 | + { |
|
255 | + |
|
256 | + /** |
|
257 | + * This array contains identifiable information of either a malicious actor |
|
258 | + * or the Vendor's support agent who is triggering the alert. |
|
259 | + * |
|
260 | + * No site user/visitor/admin data is sent back to TrustedLogin server. |
|
261 | + */ |
|
262 | + $body = [ |
|
263 | + 'timestamp' => time(), |
|
264 | + 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? substr($_SERVER['HTTP_USER_AGENT'], 0, 255) : '', |
|
265 | + 'user_ip' => $this->get_ip(), |
|
266 | + 'site_url' => get_site_url(), |
|
267 | + ]; |
|
268 | + |
|
269 | + $remote = new Remote($this->config, $this->logging); |
|
270 | + $api_response = $remote->send(self::BRUTE_FORCE_ENDPOINT, $body, 'POST'); |
|
271 | + |
|
272 | + if (is_wp_error($api_response)) { |
|
273 | + return $api_response; |
|
274 | + } |
|
275 | + |
|
276 | + $response = $remote->handle_response($api_response); |
|
277 | + |
|
278 | + if (is_wp_error($response)) { |
|
279 | + return $response; |
|
280 | + } |
|
281 | + |
|
282 | + return true; |
|
283 | + } |
|
284 | + |
|
285 | + /** |
|
286 | + * Locks down the site to new access by TrustedLogin identifiers, reports lockdown to TrustedLogin. |
|
287 | + */ |
|
288 | + private function do_lockdown() |
|
289 | + { |
|
290 | + $this->logging->log('Brute force is detected; starting lockdown.', __METHOD__, 'emergency'); |
|
291 | + |
|
292 | + $transient_set = set_site_transient($this->in_lockdown_transient, time(), self::LOCKDOWN_EXPIRY); |
|
293 | + |
|
294 | + if (!$transient_set) { |
|
295 | + $this->logging->log('Could not set the "in lockdown" transient.', __METHOD__, 'alert'); |
|
296 | + } |
|
297 | + |
|
298 | + $notified = $this->report_lockdown(); |
|
299 | + |
|
300 | + if (is_wp_error($notified)) { |
|
301 | + $this->logging->log(sprintf('Could not notify TrustedLogin (%s)', $notified->get_error_message()), __METHOD__, 'error'); |
|
302 | + } |
|
303 | + |
|
304 | + /** |
|
305 | + * Runs after the site is locked down to access from the Vendor. |
|
306 | + */ |
|
307 | + do_action('trustedlogin/'.$this->config->ns().'/lockdown/after'); |
|
308 | + } |
|
309 | + |
|
310 | + /** |
|
311 | + * Is this site in local development mode? |
|
312 | + * |
|
313 | + * @uses \wp_get_environment_type() If available, used to fetch site's development environment |
|
314 | + * |
|
315 | + * @see https://developer.wordpress.org/reference/functions/wp_get_environment_type/ |
|
316 | + * |
|
317 | + * To bypass lockdown checks, set a WordPress environment to `local` or `development`. Alternately, you may |
|
318 | + * add a constant to the site's wp-config.php file formatted as `TRUSTEDLOGIN_TESTING_{EXAMPLE}` where |
|
319 | + * `{EXAMPLE}` is replaced with the project's upper-cased namespace. |
|
320 | + * |
|
321 | + * @return bool True: site is in local or development environment. False: site is live. |
|
322 | + */ |
|
323 | + private function in_local_development() |
|
324 | + { |
|
325 | + $constant_name = 'TRUSTEDLOGIN_TESTING_'.strtoupper($this->config->ns()); |
|
326 | + |
|
327 | + if (defined($constant_name) && constant($constant_name)) { |
|
328 | + return true; |
|
329 | + } |
|
330 | + |
|
331 | + if (!function_exists('wp_get_environment_type')) { |
|
332 | + return false; |
|
333 | + } |
|
334 | + |
|
335 | + switch (wp_get_environment_type()) { |
|
336 | + case 'local': |
|
337 | + case 'development': |
|
338 | + return true; |
|
339 | + break; |
|
340 | + case 'staging': |
|
341 | + case 'production': |
|
342 | + default: |
|
343 | + } |
|
344 | + |
|
345 | + return false; |
|
346 | + } |
|
347 | + |
|
348 | + /** |
|
349 | + * Checks if TrustedLogin is currently in lockdown. |
|
350 | + * |
|
351 | + * @return int|false Int: in lockdown. The value returned is the timestamp when lockdown ends. False: not in lockdown, or overridden by a constant. |
|
352 | + */ |
|
353 | + public function in_lockdown() |
|
354 | + { |
|
355 | + if ($this->in_local_development()) { |
|
356 | + return false; |
|
357 | + } |
|
358 | + |
|
359 | + return get_site_transient($this->in_lockdown_transient); |
|
360 | + } |
|
361 | 361 | } |
@@ -61,13 +61,13 @@ discard block |
||
61 | 61 | */ |
62 | 62 | const VERIFY_SUPPORT_AGENT_ENDPOINT = 'verify-identifier'; |
63 | 63 | |
64 | - public function __construct(Config $config, Logging $logging) |
|
64 | + public function __construct( Config $config, Logging $logging ) |
|
65 | 65 | { |
66 | 66 | $this->logging = $logging; |
67 | 67 | $this->config = $config; |
68 | 68 | |
69 | - $this->used_accesskey_transient = 'tl-'.$this->config->ns().'-used_accesskeys'; |
|
70 | - $this->in_lockdown_transient = 'tl-'.$this->config->ns().'-in_lockdown'; |
|
69 | + $this->used_accesskey_transient = 'tl-' . $this->config->ns() . '-used_accesskeys'; |
|
70 | + $this->in_lockdown_transient = 'tl-' . $this->config->ns() . '-in_lockdown'; |
|
71 | 71 | } |
72 | 72 | |
73 | 73 | /** |
@@ -79,40 +79,40 @@ discard block |
||
79 | 79 | * |
80 | 80 | * @return true|WP_Error True if identifier passes checks. WP_Error if not. |
81 | 81 | */ |
82 | - public function verify($passed_user_identifier = '') |
|
82 | + public function verify( $passed_user_identifier = '' ) |
|
83 | 83 | { |
84 | 84 | $user_identifier = $passed_user_identifier; |
85 | 85 | |
86 | - if ($this->in_lockdown()) { |
|
87 | - $this->logging->log('Site is in lockdown mode, aborting login.', __METHOD__, 'error'); |
|
86 | + if ( $this->in_lockdown() ) { |
|
87 | + $this->logging->log( 'Site is in lockdown mode, aborting login.', __METHOD__, 'error' ); |
|
88 | 88 | |
89 | - return new WP_Error('in_lockdown', __('TrustedLogin temporarily disabled.', 'gravityview')); |
|
89 | + return new WP_Error( 'in_lockdown', __( 'TrustedLogin temporarily disabled.', 'gravityview' ) ); |
|
90 | 90 | } |
91 | 91 | |
92 | 92 | // When passed in the endpoint URL, the unique ID will be the raw value, not the hash. |
93 | - if (strlen($passed_user_identifier) > 32) { |
|
94 | - $user_identifier = Encryption::hash($passed_user_identifier); |
|
93 | + if ( strlen( $passed_user_identifier ) > 32 ) { |
|
94 | + $user_identifier = Encryption::hash( $passed_user_identifier ); |
|
95 | 95 | } |
96 | 96 | |
97 | - $brute_force = $this->check_brute_force($user_identifier); |
|
97 | + $brute_force = $this->check_brute_force( $user_identifier ); |
|
98 | 98 | |
99 | - if (is_wp_error($brute_force)) { |
|
99 | + if ( is_wp_error( $brute_force ) ) { |
|
100 | 100 | $this->do_lockdown(); |
101 | 101 | |
102 | 102 | return $brute_force; |
103 | 103 | } |
104 | 104 | |
105 | - $SupportUser = new SupportUser($this->config, $this->logging); |
|
105 | + $SupportUser = new SupportUser( $this->config, $this->logging ); |
|
106 | 106 | |
107 | - $secret_id = $SupportUser->get_secret_id($user_identifier); |
|
107 | + $secret_id = $SupportUser->get_secret_id( $user_identifier ); |
|
108 | 108 | |
109 | - $approved = $this->check_approved_identifier($secret_id); |
|
109 | + $approved = $this->check_approved_identifier( $secret_id ); |
|
110 | 110 | |
111 | 111 | // Don't lock-down the site, since there could have been errors related to remote validation |
112 | - if (is_wp_error($approved)) { |
|
112 | + if ( is_wp_error( $approved ) ) { |
|
113 | 113 | $this->logging->log( |
114 | 114 | sprintf( |
115 | - __('There was an issue verifying the user identifier with TrustedLogin, aborting login. (%s)', 'gravityview'), |
|
115 | + __( 'There was an issue verifying the user identifier with TrustedLogin, aborting login. (%s)', 'gravityview' ), |
|
116 | 116 | $approved->get_error_message() |
117 | 117 | ), |
118 | 118 | __METHOD__, |
@@ -132,23 +132,23 @@ discard block |
||
132 | 132 | * |
133 | 133 | * @return true|WP_Error WP_Error if an anomaly was detected and site may be under attack. Else true. |
134 | 134 | */ |
135 | - private function check_brute_force($identifier) |
|
135 | + private function check_brute_force( $identifier ) |
|
136 | 136 | { |
137 | - if ($this->in_local_development()) { |
|
137 | + if ( $this->in_local_development() ) { |
|
138 | 138 | return true; |
139 | 139 | } |
140 | 140 | |
141 | - $used_accesskeys = $this->maybe_add_used_accesskey($identifier); |
|
141 | + $used_accesskeys = $this->maybe_add_used_accesskey( $identifier ); |
|
142 | 142 | |
143 | 143 | // Is the number of attempted accesses below the lockdown limit? |
144 | - if (count($used_accesskeys) >= self::ACCESSKEY_LIMIT_COUNT) { |
|
144 | + if ( count( $used_accesskeys ) >= self::ACCESSKEY_LIMIT_COUNT ) { |
|
145 | 145 | $this->logging->log( |
146 | - 'Potential Brute Force attack detected with identifier: '.esc_attr($identifier), |
|
146 | + 'Potential Brute Force attack detected with identifier: ' . esc_attr( $identifier ), |
|
147 | 147 | __METHOD__, |
148 | 148 | 'notice' |
149 | 149 | ); |
150 | 150 | |
151 | - return new WP_Error('brute_force_detected', 'Login aborted due to potential brute force detection.'); |
|
151 | + return new WP_Error( 'brute_force_detected', 'Login aborted due to potential brute force detection.' ); |
|
152 | 152 | } |
153 | 153 | |
154 | 154 | return true; |
@@ -159,18 +159,18 @@ discard block |
||
159 | 159 | * |
160 | 160 | * @return mixed |
161 | 161 | */ |
162 | - private function maybe_add_used_accesskey($user_identifier = '') |
|
162 | + private function maybe_add_used_accesskey( $user_identifier = '' ) |
|
163 | 163 | { |
164 | - $used_accesskeys = (array) get_site_transient($this->used_accesskey_transient); |
|
164 | + $used_accesskeys = (array)get_site_transient( $this->used_accesskey_transient ); |
|
165 | 165 | |
166 | 166 | // This is a new access key |
167 | - if (!in_array($user_identifier, $used_accesskeys, true)) { |
|
168 | - $used_accesskeys[] = $user_identifier; |
|
167 | + if ( ! in_array( $user_identifier, $used_accesskeys, true ) ) { |
|
168 | + $used_accesskeys[ ] = $user_identifier; |
|
169 | 169 | |
170 | - $transient_set = set_site_transient($this->used_accesskey_transient, $used_accesskeys, self::ACCESSKEY_LIMIT_EXPIRY); |
|
170 | + $transient_set = set_site_transient( $this->used_accesskey_transient, $used_accesskeys, self::ACCESSKEY_LIMIT_EXPIRY ); |
|
171 | 171 | |
172 | - if (!$transient_set) { |
|
173 | - $this->logging->log('Used access key transient not properly set/updated.', __METHOD__, 'error'); |
|
172 | + if ( ! $transient_set ) { |
|
173 | + $this->logging->log( 'Used access key transient not properly set/updated.', __METHOD__, 'error' ); |
|
174 | 174 | } |
175 | 175 | } |
176 | 176 | |
@@ -184,19 +184,19 @@ discard block |
||
184 | 184 | */ |
185 | 185 | private function get_ip() |
186 | 186 | { |
187 | - if (!isset($_SERVER['REMOTE_ADDR'])) { |
|
187 | + if ( ! isset( $_SERVER[ 'REMOTE_ADDR' ] ) ) { |
|
188 | 188 | return null; |
189 | 189 | } |
190 | 190 | |
191 | - $ip = wp_unslash($_SERVER['REMOTE_ADDR']); |
|
191 | + $ip = wp_unslash( $_SERVER[ 'REMOTE_ADDR' ] ); |
|
192 | 192 | |
193 | - $ip = trim($ip); |
|
193 | + $ip = trim( $ip ); |
|
194 | 194 | |
195 | - if (!defined('TL_DOING_TESTS')) { |
|
196 | - $ip = filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE); |
|
195 | + if ( ! defined( 'TL_DOING_TESTS' ) ) { |
|
196 | + $ip = filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE ); |
|
197 | 197 | } |
198 | 198 | |
199 | - return (string) $ip; |
|
199 | + return (string)$ip; |
|
200 | 200 | } |
201 | 201 | |
202 | 202 | /** |
@@ -210,7 +210,7 @@ discard block |
||
210 | 210 | * |
211 | 211 | * @return true|WP_Error True: the TrustedLogin service was reached and the login remains valid. WP_Error: The service wasn't reachable or the service responded that the secret ID wasn't valid. |
212 | 212 | */ |
213 | - private function check_approved_identifier($secret_id) |
|
213 | + private function check_approved_identifier( $secret_id ) |
|
214 | 214 | { |
215 | 215 | |
216 | 216 | /** |
@@ -221,22 +221,22 @@ discard block |
||
221 | 221 | */ |
222 | 222 | $body = [ |
223 | 223 | 'timestamp' => time(), |
224 | - 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? substr($_SERVER['HTTP_USER_AGENT'], 0, 255) : '', |
|
224 | + 'user_agent' => isset( $_SERVER[ 'HTTP_USER_AGENT' ] ) ? substr( $_SERVER[ 'HTTP_USER_AGENT' ], 0, 255 ) : '', |
|
225 | 225 | 'user_ip' => $this->get_ip(), |
226 | 226 | 'site_url' => get_site_url(), |
227 | 227 | ]; |
228 | 228 | |
229 | - $remote = new Remote($this->config, $this->logging); |
|
229 | + $remote = new Remote( $this->config, $this->logging ); |
|
230 | 230 | |
231 | - $api_response = $remote->send('sites/'.$secret_id.'/'.self::VERIFY_SUPPORT_AGENT_ENDPOINT, $body, 'POST'); |
|
231 | + $api_response = $remote->send( 'sites/' . $secret_id . '/' . self::VERIFY_SUPPORT_AGENT_ENDPOINT, $body, 'POST' ); |
|
232 | 232 | |
233 | - if (is_wp_error($api_response)) { |
|
233 | + if ( is_wp_error( $api_response ) ) { |
|
234 | 234 | return $api_response; |
235 | 235 | } |
236 | 236 | |
237 | - $response = $remote->handle_response($api_response); |
|
237 | + $response = $remote->handle_response( $api_response ); |
|
238 | 238 | |
239 | - if (is_wp_error($response)) { |
|
239 | + if ( is_wp_error( $response ) ) { |
|
240 | 240 | return $response; |
241 | 241 | } |
242 | 242 | |
@@ -261,21 +261,21 @@ discard block |
||
261 | 261 | */ |
262 | 262 | $body = [ |
263 | 263 | 'timestamp' => time(), |
264 | - 'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? substr($_SERVER['HTTP_USER_AGENT'], 0, 255) : '', |
|
264 | + 'user_agent' => isset( $_SERVER[ 'HTTP_USER_AGENT' ] ) ? substr( $_SERVER[ 'HTTP_USER_AGENT' ], 0, 255 ) : '', |
|
265 | 265 | 'user_ip' => $this->get_ip(), |
266 | 266 | 'site_url' => get_site_url(), |
267 | 267 | ]; |
268 | 268 | |
269 | - $remote = new Remote($this->config, $this->logging); |
|
270 | - $api_response = $remote->send(self::BRUTE_FORCE_ENDPOINT, $body, 'POST'); |
|
269 | + $remote = new Remote( $this->config, $this->logging ); |
|
270 | + $api_response = $remote->send( self::BRUTE_FORCE_ENDPOINT, $body, 'POST' ); |
|
271 | 271 | |
272 | - if (is_wp_error($api_response)) { |
|
272 | + if ( is_wp_error( $api_response ) ) { |
|
273 | 273 | return $api_response; |
274 | 274 | } |
275 | 275 | |
276 | - $response = $remote->handle_response($api_response); |
|
276 | + $response = $remote->handle_response( $api_response ); |
|
277 | 277 | |
278 | - if (is_wp_error($response)) { |
|
278 | + if ( is_wp_error( $response ) ) { |
|
279 | 279 | return $response; |
280 | 280 | } |
281 | 281 | |
@@ -287,24 +287,24 @@ discard block |
||
287 | 287 | */ |
288 | 288 | private function do_lockdown() |
289 | 289 | { |
290 | - $this->logging->log('Brute force is detected; starting lockdown.', __METHOD__, 'emergency'); |
|
290 | + $this->logging->log( 'Brute force is detected; starting lockdown.', __METHOD__, 'emergency' ); |
|
291 | 291 | |
292 | - $transient_set = set_site_transient($this->in_lockdown_transient, time(), self::LOCKDOWN_EXPIRY); |
|
292 | + $transient_set = set_site_transient( $this->in_lockdown_transient, time(), self::LOCKDOWN_EXPIRY ); |
|
293 | 293 | |
294 | - if (!$transient_set) { |
|
295 | - $this->logging->log('Could not set the "in lockdown" transient.', __METHOD__, 'alert'); |
|
294 | + if ( ! $transient_set ) { |
|
295 | + $this->logging->log( 'Could not set the "in lockdown" transient.', __METHOD__, 'alert' ); |
|
296 | 296 | } |
297 | 297 | |
298 | 298 | $notified = $this->report_lockdown(); |
299 | 299 | |
300 | - if (is_wp_error($notified)) { |
|
301 | - $this->logging->log(sprintf('Could not notify TrustedLogin (%s)', $notified->get_error_message()), __METHOD__, 'error'); |
|
300 | + if ( is_wp_error( $notified ) ) { |
|
301 | + $this->logging->log( sprintf( 'Could not notify TrustedLogin (%s)', $notified->get_error_message() ), __METHOD__, 'error' ); |
|
302 | 302 | } |
303 | 303 | |
304 | 304 | /** |
305 | 305 | * Runs after the site is locked down to access from the Vendor. |
306 | 306 | */ |
307 | - do_action('trustedlogin/'.$this->config->ns().'/lockdown/after'); |
|
307 | + do_action( 'trustedlogin/' . $this->config->ns() . '/lockdown/after' ); |
|
308 | 308 | } |
309 | 309 | |
310 | 310 | /** |
@@ -322,17 +322,17 @@ discard block |
||
322 | 322 | */ |
323 | 323 | private function in_local_development() |
324 | 324 | { |
325 | - $constant_name = 'TRUSTEDLOGIN_TESTING_'.strtoupper($this->config->ns()); |
|
325 | + $constant_name = 'TRUSTEDLOGIN_TESTING_' . strtoupper( $this->config->ns() ); |
|
326 | 326 | |
327 | - if (defined($constant_name) && constant($constant_name)) { |
|
327 | + if ( defined( $constant_name ) && constant( $constant_name ) ) { |
|
328 | 328 | return true; |
329 | 329 | } |
330 | 330 | |
331 | - if (!function_exists('wp_get_environment_type')) { |
|
331 | + if ( ! function_exists( 'wp_get_environment_type' ) ) { |
|
332 | 332 | return false; |
333 | 333 | } |
334 | 334 | |
335 | - switch (wp_get_environment_type()) { |
|
335 | + switch ( wp_get_environment_type() ) { |
|
336 | 336 | case 'local': |
337 | 337 | case 'development': |
338 | 338 | return true; |
@@ -352,10 +352,10 @@ discard block |
||
352 | 352 | */ |
353 | 353 | public function in_lockdown() |
354 | 354 | { |
355 | - if ($this->in_local_development()) { |
|
355 | + if ( $this->in_local_development() ) { |
|
356 | 356 | return false; |
357 | 357 | } |
358 | 358 | |
359 | - return get_site_transient($this->in_lockdown_transient); |
|
359 | + return get_site_transient( $this->in_lockdown_transient ); |
|
360 | 360 | } |
361 | 361 | } |
@@ -14,8 +14,7 @@ discard block |
||
14 | 14 | |
15 | 15 | use WP_Error; |
16 | 16 | |
17 | -final class SecurityChecks |
|
18 | -{ |
|
17 | +final class SecurityChecks { |
|
19 | 18 | /** |
20 | 19 | * @var Logging |
21 | 20 | */ |
@@ -61,8 +60,7 @@ discard block |
||
61 | 60 | */ |
62 | 61 | const VERIFY_SUPPORT_AGENT_ENDPOINT = 'verify-identifier'; |
63 | 62 | |
64 | - public function __construct(Config $config, Logging $logging) |
|
65 | - { |
|
63 | + public function __construct(Config $config, Logging $logging) { |
|
66 | 64 | $this->logging = $logging; |
67 | 65 | $this->config = $config; |
68 | 66 | |
@@ -79,8 +77,7 @@ discard block |
||
79 | 77 | * |
80 | 78 | * @return true|WP_Error True if identifier passes checks. WP_Error if not. |
81 | 79 | */ |
82 | - public function verify($passed_user_identifier = '') |
|
83 | - { |
|
80 | + public function verify($passed_user_identifier = '') { |
|
84 | 81 | $user_identifier = $passed_user_identifier; |
85 | 82 | |
86 | 83 | if ($this->in_lockdown()) { |
@@ -132,8 +129,7 @@ discard block |
||
132 | 129 | * |
133 | 130 | * @return true|WP_Error WP_Error if an anomaly was detected and site may be under attack. Else true. |
134 | 131 | */ |
135 | - private function check_brute_force($identifier) |
|
136 | - { |
|
132 | + private function check_brute_force($identifier) { |
|
137 | 133 | if ($this->in_local_development()) { |
138 | 134 | return true; |
139 | 135 | } |
@@ -159,8 +155,7 @@ discard block |
||
159 | 155 | * |
160 | 156 | * @return mixed |
161 | 157 | */ |
162 | - private function maybe_add_used_accesskey($user_identifier = '') |
|
163 | - { |
|
158 | + private function maybe_add_used_accesskey($user_identifier = '') { |
|
164 | 159 | $used_accesskeys = (array) get_site_transient($this->used_accesskey_transient); |
165 | 160 | |
166 | 161 | // This is a new access key |
@@ -182,8 +177,7 @@ discard block |
||
182 | 177 | * |
183 | 178 | * @return null|string Returns null if REMOTE_ADDR isn't set, string IP address otherwise. |
184 | 179 | */ |
185 | - private function get_ip() |
|
186 | - { |
|
180 | + private function get_ip() { |
|
187 | 181 | if (!isset($_SERVER['REMOTE_ADDR'])) { |
188 | 182 | return null; |
189 | 183 | } |
@@ -210,8 +204,7 @@ discard block |
||
210 | 204 | * |
211 | 205 | * @return true|WP_Error True: the TrustedLogin service was reached and the login remains valid. WP_Error: The service wasn't reachable or the service responded that the secret ID wasn't valid. |
212 | 206 | */ |
213 | - private function check_approved_identifier($secret_id) |
|
214 | - { |
|
207 | + private function check_approved_identifier($secret_id) { |
|
215 | 208 | |
216 | 209 | /** |
217 | 210 | * This array contains information from the Vendor's support agent |
@@ -250,8 +243,7 @@ discard block |
||
250 | 243 | * |
251 | 244 | * @return true|WP_Error If the notification was sent, returns true, otherwise WP_Error on issue. |
252 | 245 | */ |
253 | - private function report_lockdown() |
|
254 | - { |
|
246 | + private function report_lockdown() { |
|
255 | 247 | |
256 | 248 | /** |
257 | 249 | * This array contains identifiable information of either a malicious actor |
@@ -285,8 +277,7 @@ discard block |
||
285 | 277 | /** |
286 | 278 | * Locks down the site to new access by TrustedLogin identifiers, reports lockdown to TrustedLogin. |
287 | 279 | */ |
288 | - private function do_lockdown() |
|
289 | - { |
|
280 | + private function do_lockdown() { |
|
290 | 281 | $this->logging->log('Brute force is detected; starting lockdown.', __METHOD__, 'emergency'); |
291 | 282 | |
292 | 283 | $transient_set = set_site_transient($this->in_lockdown_transient, time(), self::LOCKDOWN_EXPIRY); |
@@ -320,8 +311,7 @@ discard block |
||
320 | 311 | * |
321 | 312 | * @return bool True: site is in local or development environment. False: site is live. |
322 | 313 | */ |
323 | - private function in_local_development() |
|
324 | - { |
|
314 | + private function in_local_development() { |
|
325 | 315 | $constant_name = 'TRUSTEDLOGIN_TESTING_'.strtoupper($this->config->ns()); |
326 | 316 | |
327 | 317 | if (defined($constant_name) && constant($constant_name)) { |
@@ -350,8 +340,7 @@ discard block |
||
350 | 340 | * |
351 | 341 | * @return int|false Int: in lockdown. The value returned is the timestamp when lockdown ends. False: not in lockdown, or overridden by a constant. |
352 | 342 | */ |
353 | - public function in_lockdown() |
|
354 | - { |
|
343 | + public function in_lockdown() { |
|
355 | 344 | if ($this->in_local_development()) { |
356 | 345 | return false; |
357 | 346 | } |
@@ -14,7 +14,7 @@ discard block |
||
14 | 14 | |
15 | 15 | // Exit if accessed directly |
16 | 16 | if (!defined('ABSPATH')) { |
17 | - exit; |
|
17 | + exit; |
|
18 | 18 | } |
19 | 19 | |
20 | 20 | use WP_Error; |
@@ -24,101 +24,101 @@ discard block |
||
24 | 24 | */ |
25 | 25 | final class Envelope |
26 | 26 | { |
27 | - /** |
|
28 | - * @var Config |
|
29 | - */ |
|
30 | - private $config; |
|
31 | - |
|
32 | - /** |
|
33 | - * @var Encryption |
|
34 | - */ |
|
35 | - private $encryption; |
|
36 | - |
|
37 | - /** |
|
38 | - * @var string API key set in software. |
|
39 | - */ |
|
40 | - private $api_key; |
|
41 | - |
|
42 | - /** |
|
43 | - * Envelope constructor. |
|
44 | - * |
|
45 | - * @param Config $config |
|
46 | - * @param Encryption $encryption |
|
47 | - */ |
|
48 | - public function __construct(Config $config, Encryption $encryption) |
|
49 | - { |
|
50 | - $this->config = $config; |
|
51 | - $this->api_key = $this->config->get_setting('auth/api_key'); |
|
52 | - $this->encryption = $encryption; |
|
53 | - } |
|
54 | - |
|
55 | - /** |
|
56 | - * @param string $secret_id |
|
57 | - * @param string $site_identifier_hash |
|
58 | - * @param string $access_key |
|
59 | - * |
|
60 | - * @return array|WP_Error |
|
61 | - */ |
|
62 | - public function get($secret_id, $site_identifier_hash, $access_key = '') |
|
63 | - { |
|
64 | - if (!is_string($secret_id)) { |
|
65 | - return new WP_Error('secret_not_string', 'The secret ID must be a string:'.print_r($secret_id, true)); |
|
66 | - } |
|
67 | - |
|
68 | - if (!is_string($site_identifier_hash)) { |
|
69 | - return new WP_Error('site_identifier_not_string', 'The site identifier must be a string:'.print_r($site_identifier_hash, true)); |
|
70 | - } |
|
71 | - |
|
72 | - if (!is_string($access_key)) { |
|
73 | - return new WP_Error('access_key_not_string', 'The access key must be a string: '.print_r($access_key, true)); |
|
74 | - } |
|
75 | - |
|
76 | - if (!function_exists('sodium_bin2hex')) { |
|
77 | - return new WP_Error('sodium_bin2hex_not_available', 'The sodium_bin2hex function is not available.'); |
|
78 | - } |
|
79 | - |
|
80 | - $e_keys = $this->encryption->generate_keys(); |
|
81 | - |
|
82 | - if (is_wp_error($e_keys)) { |
|
83 | - return $e_keys; |
|
84 | - } |
|
85 | - |
|
86 | - $nonce = $this->encryption->get_nonce(); |
|
87 | - |
|
88 | - if (is_wp_error($nonce)) { |
|
89 | - return $nonce; |
|
90 | - } |
|
91 | - |
|
92 | - $encrypted_identifier = $this->encryption->encrypt($site_identifier_hash, $nonce, $e_keys->privateKey); |
|
93 | - |
|
94 | - if (is_wp_error($encrypted_identifier)) { |
|
95 | - return $encrypted_identifier; |
|
96 | - } |
|
97 | - |
|
98 | - /** |
|
99 | - * Adds custom meta data to be synced via TrustedLogin. |
|
100 | - * |
|
101 | - * WARNING: Meta data is transferred and stored in plain text, and **must not contain any sensitive or identifiable information**! |
|
102 | - * |
|
103 | - * @since 1.0.0 |
|
104 | - * |
|
105 | - * @param array $metadata |
|
106 | - * @param Config $config Current TrustedLogin configuration |
|
107 | - */ |
|
108 | - $metadata = apply_filters('trustedlogin/'.$this->config->ns().'/envelope/meta', [], $this->config); |
|
109 | - |
|
110 | - return [ |
|
111 | - 'secretId' => $secret_id, |
|
112 | - 'identifier' => $encrypted_identifier, |
|
113 | - 'siteUrl' => get_site_url(), |
|
114 | - 'publicKey' => $this->api_key, |
|
115 | - 'accessKey' => $access_key, |
|
116 | - 'wpUserId' => get_current_user_id(), |
|
117 | - 'expiresAt' => $this->config->get_expiration_timestamp(null, true), |
|
118 | - 'version' => Client::VERSION, |
|
119 | - 'nonce' => \sodium_bin2hex($nonce), |
|
120 | - 'clientPublicKey' => \sodium_bin2hex($e_keys->publicKey), |
|
121 | - 'metaData' => $metadata, |
|
122 | - ]; |
|
123 | - } |
|
27 | + /** |
|
28 | + * @var Config |
|
29 | + */ |
|
30 | + private $config; |
|
31 | + |
|
32 | + /** |
|
33 | + * @var Encryption |
|
34 | + */ |
|
35 | + private $encryption; |
|
36 | + |
|
37 | + /** |
|
38 | + * @var string API key set in software. |
|
39 | + */ |
|
40 | + private $api_key; |
|
41 | + |
|
42 | + /** |
|
43 | + * Envelope constructor. |
|
44 | + * |
|
45 | + * @param Config $config |
|
46 | + * @param Encryption $encryption |
|
47 | + */ |
|
48 | + public function __construct(Config $config, Encryption $encryption) |
|
49 | + { |
|
50 | + $this->config = $config; |
|
51 | + $this->api_key = $this->config->get_setting('auth/api_key'); |
|
52 | + $this->encryption = $encryption; |
|
53 | + } |
|
54 | + |
|
55 | + /** |
|
56 | + * @param string $secret_id |
|
57 | + * @param string $site_identifier_hash |
|
58 | + * @param string $access_key |
|
59 | + * |
|
60 | + * @return array|WP_Error |
|
61 | + */ |
|
62 | + public function get($secret_id, $site_identifier_hash, $access_key = '') |
|
63 | + { |
|
64 | + if (!is_string($secret_id)) { |
|
65 | + return new WP_Error('secret_not_string', 'The secret ID must be a string:'.print_r($secret_id, true)); |
|
66 | + } |
|
67 | + |
|
68 | + if (!is_string($site_identifier_hash)) { |
|
69 | + return new WP_Error('site_identifier_not_string', 'The site identifier must be a string:'.print_r($site_identifier_hash, true)); |
|
70 | + } |
|
71 | + |
|
72 | + if (!is_string($access_key)) { |
|
73 | + return new WP_Error('access_key_not_string', 'The access key must be a string: '.print_r($access_key, true)); |
|
74 | + } |
|
75 | + |
|
76 | + if (!function_exists('sodium_bin2hex')) { |
|
77 | + return new WP_Error('sodium_bin2hex_not_available', 'The sodium_bin2hex function is not available.'); |
|
78 | + } |
|
79 | + |
|
80 | + $e_keys = $this->encryption->generate_keys(); |
|
81 | + |
|
82 | + if (is_wp_error($e_keys)) { |
|
83 | + return $e_keys; |
|
84 | + } |
|
85 | + |
|
86 | + $nonce = $this->encryption->get_nonce(); |
|
87 | + |
|
88 | + if (is_wp_error($nonce)) { |
|
89 | + return $nonce; |
|
90 | + } |
|
91 | + |
|
92 | + $encrypted_identifier = $this->encryption->encrypt($site_identifier_hash, $nonce, $e_keys->privateKey); |
|
93 | + |
|
94 | + if (is_wp_error($encrypted_identifier)) { |
|
95 | + return $encrypted_identifier; |
|
96 | + } |
|
97 | + |
|
98 | + /** |
|
99 | + * Adds custom meta data to be synced via TrustedLogin. |
|
100 | + * |
|
101 | + * WARNING: Meta data is transferred and stored in plain text, and **must not contain any sensitive or identifiable information**! |
|
102 | + * |
|
103 | + * @since 1.0.0 |
|
104 | + * |
|
105 | + * @param array $metadata |
|
106 | + * @param Config $config Current TrustedLogin configuration |
|
107 | + */ |
|
108 | + $metadata = apply_filters('trustedlogin/'.$this->config->ns().'/envelope/meta', [], $this->config); |
|
109 | + |
|
110 | + return [ |
|
111 | + 'secretId' => $secret_id, |
|
112 | + 'identifier' => $encrypted_identifier, |
|
113 | + 'siteUrl' => get_site_url(), |
|
114 | + 'publicKey' => $this->api_key, |
|
115 | + 'accessKey' => $access_key, |
|
116 | + 'wpUserId' => get_current_user_id(), |
|
117 | + 'expiresAt' => $this->config->get_expiration_timestamp(null, true), |
|
118 | + 'version' => Client::VERSION, |
|
119 | + 'nonce' => \sodium_bin2hex($nonce), |
|
120 | + 'clientPublicKey' => \sodium_bin2hex($e_keys->publicKey), |
|
121 | + 'metaData' => $metadata, |
|
122 | + ]; |
|
123 | + } |
|
124 | 124 | } |
@@ -13,7 +13,7 @@ discard block |
||
13 | 13 | namespace GravityView\TrustedLogin; |
14 | 14 | |
15 | 15 | // Exit if accessed directly |
16 | -if (!defined('ABSPATH')) { |
|
16 | +if ( ! defined( 'ABSPATH' ) ) { |
|
17 | 17 | exit; |
18 | 18 | } |
19 | 19 | |
@@ -45,10 +45,10 @@ discard block |
||
45 | 45 | * @param Config $config |
46 | 46 | * @param Encryption $encryption |
47 | 47 | */ |
48 | - public function __construct(Config $config, Encryption $encryption) |
|
48 | + public function __construct( Config $config, Encryption $encryption ) |
|
49 | 49 | { |
50 | 50 | $this->config = $config; |
51 | - $this->api_key = $this->config->get_setting('auth/api_key'); |
|
51 | + $this->api_key = $this->config->get_setting( 'auth/api_key' ); |
|
52 | 52 | $this->encryption = $encryption; |
53 | 53 | } |
54 | 54 | |
@@ -59,39 +59,39 @@ discard block |
||
59 | 59 | * |
60 | 60 | * @return array|WP_Error |
61 | 61 | */ |
62 | - public function get($secret_id, $site_identifier_hash, $access_key = '') |
|
62 | + public function get( $secret_id, $site_identifier_hash, $access_key = '' ) |
|
63 | 63 | { |
64 | - if (!is_string($secret_id)) { |
|
65 | - return new WP_Error('secret_not_string', 'The secret ID must be a string:'.print_r($secret_id, true)); |
|
64 | + if ( ! is_string( $secret_id ) ) { |
|
65 | + return new WP_Error( 'secret_not_string', 'The secret ID must be a string:' . print_r( $secret_id, true ) ); |
|
66 | 66 | } |
67 | 67 | |
68 | - if (!is_string($site_identifier_hash)) { |
|
69 | - return new WP_Error('site_identifier_not_string', 'The site identifier must be a string:'.print_r($site_identifier_hash, true)); |
|
68 | + if ( ! is_string( $site_identifier_hash ) ) { |
|
69 | + return new WP_Error( 'site_identifier_not_string', 'The site identifier must be a string:' . print_r( $site_identifier_hash, true ) ); |
|
70 | 70 | } |
71 | 71 | |
72 | - if (!is_string($access_key)) { |
|
73 | - return new WP_Error('access_key_not_string', 'The access key must be a string: '.print_r($access_key, true)); |
|
72 | + if ( ! is_string( $access_key ) ) { |
|
73 | + return new WP_Error( 'access_key_not_string', 'The access key must be a string: ' . print_r( $access_key, true ) ); |
|
74 | 74 | } |
75 | 75 | |
76 | - if (!function_exists('sodium_bin2hex')) { |
|
77 | - return new WP_Error('sodium_bin2hex_not_available', 'The sodium_bin2hex function is not available.'); |
|
76 | + if ( ! function_exists( 'sodium_bin2hex' ) ) { |
|
77 | + return new WP_Error( 'sodium_bin2hex_not_available', 'The sodium_bin2hex function is not available.' ); |
|
78 | 78 | } |
79 | 79 | |
80 | 80 | $e_keys = $this->encryption->generate_keys(); |
81 | 81 | |
82 | - if (is_wp_error($e_keys)) { |
|
82 | + if ( is_wp_error( $e_keys ) ) { |
|
83 | 83 | return $e_keys; |
84 | 84 | } |
85 | 85 | |
86 | 86 | $nonce = $this->encryption->get_nonce(); |
87 | 87 | |
88 | - if (is_wp_error($nonce)) { |
|
88 | + if ( is_wp_error( $nonce ) ) { |
|
89 | 89 | return $nonce; |
90 | 90 | } |
91 | 91 | |
92 | - $encrypted_identifier = $this->encryption->encrypt($site_identifier_hash, $nonce, $e_keys->privateKey); |
|
92 | + $encrypted_identifier = $this->encryption->encrypt( $site_identifier_hash, $nonce, $e_keys->privateKey ); |
|
93 | 93 | |
94 | - if (is_wp_error($encrypted_identifier)) { |
|
94 | + if ( is_wp_error( $encrypted_identifier ) ) { |
|
95 | 95 | return $encrypted_identifier; |
96 | 96 | } |
97 | 97 | |
@@ -105,7 +105,7 @@ discard block |
||
105 | 105 | * @param array $metadata |
106 | 106 | * @param Config $config Current TrustedLogin configuration |
107 | 107 | */ |
108 | - $metadata = apply_filters('trustedlogin/'.$this->config->ns().'/envelope/meta', [], $this->config); |
|
108 | + $metadata = apply_filters( 'trustedlogin/' . $this->config->ns() . '/envelope/meta', [ ], $this->config ); |
|
109 | 109 | |
110 | 110 | return [ |
111 | 111 | 'secretId' => $secret_id, |
@@ -114,10 +114,10 @@ discard block |
||
114 | 114 | 'publicKey' => $this->api_key, |
115 | 115 | 'accessKey' => $access_key, |
116 | 116 | 'wpUserId' => get_current_user_id(), |
117 | - 'expiresAt' => $this->config->get_expiration_timestamp(null, true), |
|
117 | + 'expiresAt' => $this->config->get_expiration_timestamp( null, true ), |
|
118 | 118 | 'version' => Client::VERSION, |
119 | - 'nonce' => \sodium_bin2hex($nonce), |
|
120 | - 'clientPublicKey' => \sodium_bin2hex($e_keys->publicKey), |
|
119 | + 'nonce' => \sodium_bin2hex( $nonce ), |
|
120 | + 'clientPublicKey' => \sodium_bin2hex( $e_keys->publicKey ), |
|
121 | 121 | 'metaData' => $metadata, |
122 | 122 | ]; |
123 | 123 | } |
@@ -22,8 +22,7 @@ discard block |
||
22 | 22 | /** |
23 | 23 | * The TrustedLogin all-in-one drop-in class. |
24 | 24 | */ |
25 | -final class Envelope |
|
26 | -{ |
|
25 | +final class Envelope { |
|
27 | 26 | /** |
28 | 27 | * @var Config |
29 | 28 | */ |
@@ -45,8 +44,7 @@ discard block |
||
45 | 44 | * @param Config $config |
46 | 45 | * @param Encryption $encryption |
47 | 46 | */ |
48 | - public function __construct(Config $config, Encryption $encryption) |
|
49 | - { |
|
47 | + public function __construct(Config $config, Encryption $encryption) { |
|
50 | 48 | $this->config = $config; |
51 | 49 | $this->api_key = $this->config->get_setting('auth/api_key'); |
52 | 50 | $this->encryption = $encryption; |
@@ -59,8 +57,7 @@ discard block |
||
59 | 57 | * |
60 | 58 | * @return array|WP_Error |
61 | 59 | */ |
62 | - public function get($secret_id, $site_identifier_hash, $access_key = '') |
|
63 | - { |
|
60 | + public function get($secret_id, $site_identifier_hash, $access_key = '') { |
|
64 | 61 | if (!is_string($secret_id)) { |
65 | 62 | return new WP_Error('secret_not_string', 'The secret ID must be a string:'.print_r($secret_id, true)); |
66 | 63 | } |
@@ -14,7 +14,7 @@ discard block |
||
14 | 14 | |
15 | 15 | // Exit if accessed directly |
16 | 16 | if (!defined('ABSPATH')) { |
17 | - exit; |
|
17 | + exit; |
|
18 | 18 | } |
19 | 19 | |
20 | 20 | use Sodium; |
@@ -22,348 +22,348 @@ discard block |
||
22 | 22 | |
23 | 23 | final class Encryption |
24 | 24 | { |
25 | - /** |
|
26 | - * @var Config |
|
27 | - */ |
|
28 | - private $config; |
|
29 | - |
|
30 | - /** |
|
31 | - * @var Remote |
|
32 | - */ |
|
33 | - private $remote; |
|
34 | - |
|
35 | - /** |
|
36 | - * @var Logging |
|
37 | - */ |
|
38 | - private $logging; |
|
39 | - |
|
40 | - /** |
|
41 | - * @var string Where the plugin should store the public key for encrypting data |
|
42 | - * |
|
43 | - * @since 1.0.0 |
|
44 | - */ |
|
45 | - private $vendor_public_key_option; |
|
46 | - |
|
47 | - /** |
|
48 | - * @var string Endpoint path to Vendor public key. |
|
49 | - */ |
|
50 | - private $vendor_public_key_endpoint = 'wp-json/trustedlogin/v1/public_key'; |
|
51 | - |
|
52 | - /** |
|
53 | - * Encryption constructor. |
|
54 | - * |
|
55 | - * @param Config $config |
|
56 | - * @param Remote $remote |
|
57 | - * @param Logging $logging |
|
58 | - */ |
|
59 | - public function __construct(Config $config, Remote $remote, Logging $logging) |
|
60 | - { |
|
61 | - $this->config = $config; |
|
62 | - $this->remote = $remote; |
|
63 | - $this->logging = $logging; |
|
64 | - |
|
65 | - /** |
|
66 | - * Filter: Sets the site option name for the Public Key for encryption functions. |
|
67 | - * |
|
68 | - * @since 1.0.0 |
|
69 | - * |
|
70 | - * @param string $vendor_public_key_option |
|
71 | - * @param Config $config |
|
72 | - */ |
|
73 | - $this->vendor_public_key_option = apply_filters( |
|
74 | - 'trustedlogin/'.$this->config->ns().'/options/vendor_public_key', |
|
75 | - 'tl_'.$this->config->ns().'_vendor_public_key', |
|
76 | - $this->config |
|
77 | - ); |
|
78 | - } |
|
79 | - |
|
80 | - /** |
|
81 | - * Generates a random hash 64 characters long. |
|
82 | - * |
|
83 | - * If random_bytes() and openssl_random_pseudo_bytes() don't exist, returns WP_Error with code generate_hash_failed. |
|
84 | - * |
|
85 | - * If random_bytes() does not exist and openssl_random_pseudo_bytes() is unable to return a strong result, |
|
86 | - * returns a WP_Error with code `openssl_not_strong_crypto`. |
|
87 | - * |
|
88 | - * @uses random_bytes |
|
89 | - * @uses openssl_random_pseudo_bytes Only used if random_bytes() does not exist. |
|
90 | - * |
|
91 | - * @param Logging The logging object to use |
|
92 | - * |
|
93 | - * @return string|WP_Error 64-character random hash or a WP_Error object explaining what went wrong. See docblock. |
|
94 | - */ |
|
95 | - public static function get_random_hash($logging) |
|
96 | - { |
|
97 | - $byte_length = 64; |
|
98 | - |
|
99 | - $hash = false; |
|
100 | - |
|
101 | - if (function_exists('random_bytes')) { |
|
102 | - try { |
|
103 | - $bytes = random_bytes($byte_length); |
|
104 | - $hash = bin2hex($bytes); |
|
105 | - } catch (\TypeError $e) { |
|
106 | - $logging->log($e->getMessage(), __METHOD__, 'error'); |
|
107 | - } catch (\Error $e) { |
|
108 | - $logging->log($e->getMessage(), __METHOD__, 'error'); |
|
109 | - } catch (\Exception $e) { |
|
110 | - $logging->log($e->getMessage(), __METHOD__, 'error'); |
|
111 | - } |
|
112 | - } else { |
|
113 | - $logging->log('This site does not have the random_bytes() function.', __METHOD__, 'debug'); |
|
114 | - } |
|
115 | - |
|
116 | - if ($hash) { |
|
117 | - return $hash; |
|
118 | - } |
|
119 | - |
|
120 | - if (!function_exists('openssl_random_pseudo_bytes')) { |
|
121 | - return new WP_Error('generate_hash_failed', 'Could not generate a secure hash with random_bytes or openssl.'); |
|
122 | - } |
|
123 | - |
|
124 | - $crypto_strong = false; |
|
125 | - $hash = openssl_random_pseudo_bytes($byte_length, $crypto_strong); |
|
126 | - |
|
127 | - if (!$crypto_strong) { |
|
128 | - return new WP_Error('openssl_not_strong_crypto', 'Site could not generate a secure hash with OpenSSL.'); |
|
129 | - } |
|
130 | - |
|
131 | - return $hash; |
|
132 | - } |
|
133 | - |
|
134 | - /** |
|
135 | - * @param $string |
|
136 | - * |
|
137 | - * @return string|WP_Error |
|
138 | - */ |
|
139 | - public static function hash($string, $length = 16) |
|
140 | - { |
|
141 | - if (!function_exists('sodium_crypto_generichash')) { |
|
142 | - return new WP_Error('sodium_crypto_generichash_not_available', 'sodium_crypto_generichash not available'); |
|
143 | - } |
|
144 | - |
|
145 | - try { |
|
146 | - $hash_bin = sodium_crypto_generichash($string, '', (int) $length); |
|
147 | - $hash = sodium_bin2hex($hash_bin); |
|
148 | - } catch (\TypeError $e) { |
|
149 | - return new WP_Error( |
|
150 | - 'encryption_failed_generichash_typeerror', |
|
151 | - sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
152 | - ); |
|
153 | - } catch (\Error $e) { |
|
154 | - return new WP_Error( |
|
155 | - 'encryption_failed_generichash_error', |
|
156 | - sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
157 | - ); |
|
158 | - } catch (\SodiumException $e) { |
|
159 | - return new WP_Error( |
|
160 | - 'encryption_failed_generichash_sodium', |
|
161 | - sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
162 | - ); |
|
163 | - } catch (\Exception $e) { |
|
164 | - return new WP_Error( |
|
165 | - 'encryption_failed_generichash', |
|
166 | - sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
167 | - ); |
|
168 | - } |
|
169 | - |
|
170 | - return $hash; |
|
171 | - } |
|
172 | - |
|
173 | - /** |
|
174 | - * Fetches the Public Key from local or db. |
|
175 | - * |
|
176 | - * @since 1.0.0 |
|
177 | - * |
|
178 | - * @return string|WP_Error If found, it returns the publicKey, if not a WP_Error |
|
179 | - */ |
|
180 | - public function get_vendor_public_key() |
|
181 | - { |
|
182 | - |
|
183 | - // Already stored as transient |
|
184 | - $public_key = get_site_transient($this->vendor_public_key_option); |
|
185 | - |
|
186 | - if ($public_key) { |
|
187 | - // Documented below |
|
188 | - return apply_filters('trustedlogin/'.$this->config->ns().'/vendor_public_key', $public_key, $this->config); |
|
189 | - } |
|
190 | - |
|
191 | - // Fetch a key from Vendor site |
|
192 | - $remote_key = $this->get_remote_encryption_key(); |
|
193 | - |
|
194 | - if (is_wp_error($remote_key)) { |
|
195 | - $this->logging->log(sprintf('(%s) %s', $remote_key->get_error_code(), $remote_key->get_error_message()), __METHOD__, 'notice'); |
|
196 | - |
|
197 | - return $remote_key; |
|
198 | - } |
|
199 | - |
|
200 | - // Attempt to store Vendor public key in the DB for ten minutes (may be overridden by caching plugins) |
|
201 | - $saved = set_site_transient($this->vendor_public_key_option, $remote_key, 60 * 10); |
|
202 | - |
|
203 | - if (!$saved) { |
|
204 | - $this->logging->log('Public key not saved after being fetched remotely.', __METHOD__, 'warning'); |
|
205 | - } |
|
206 | - |
|
207 | - /** |
|
208 | - * Filter: Override the public key functions. |
|
209 | - * |
|
210 | - * @since 1.0.0 |
|
211 | - * |
|
212 | - * @param string $vendor_public_key |
|
213 | - * @param Config $config |
|
214 | - */ |
|
215 | - return apply_filters('trustedlogin/'.$this->config->ns().'/vendor_public_key', $remote_key, $this->config); |
|
216 | - } |
|
217 | - |
|
218 | - /** |
|
219 | - * Fetches the Public Key from the `TrustedLogin-vendor` plugin on support website. |
|
220 | - * |
|
221 | - * @since 1.0.0 |
|
222 | - * |
|
223 | - * @return string|WP_Error If successful, will return the Public Key string. Otherwise WP_Error on failure. |
|
224 | - */ |
|
225 | - private function get_remote_encryption_key() |
|
226 | - { |
|
227 | - $vendor_url = $this->config->get_setting('vendor/website'); |
|
228 | - |
|
229 | - /** |
|
230 | - * @param string $key_endpoint Endpoint path on vendor (software vendor's) site |
|
231 | - */ |
|
232 | - $key_endpoint = apply_filters('trustedlogin/'.$this->config->ns().'/vendor/public_key/endpoint', $this->vendor_public_key_endpoint); |
|
233 | - |
|
234 | - $url = trailingslashit($vendor_url).$key_endpoint; |
|
235 | - |
|
236 | - $headers = [ |
|
237 | - 'Accept' => 'application/json', |
|
238 | - 'Content-Type' => 'application/json', |
|
239 | - ]; |
|
240 | - |
|
241 | - $request_options = [ |
|
242 | - 'method' => 'GET', |
|
243 | - 'timeout' => 45, |
|
244 | - 'httpversion' => '1.1', |
|
245 | - 'headers' => $headers, |
|
246 | - ]; |
|
247 | - |
|
248 | - $response = wp_remote_request($url, $request_options); |
|
249 | - |
|
250 | - $response_json = $this->remote->handle_response($response, ['publicKey']); |
|
251 | - |
|
252 | - if (is_wp_error($response_json)) { |
|
253 | - if ('not_found' == $response_json->get_error_code()) { |
|
254 | - return new WP_Error('not_found', __('Encryption key could not be fetched, Vendor site returned 404.', 'gravityview')); |
|
255 | - } |
|
256 | - |
|
257 | - return $response_json; |
|
258 | - } |
|
259 | - |
|
260 | - return $response_json['publicKey']; |
|
261 | - } |
|
262 | - |
|
263 | - /** |
|
264 | - * Encrypts a string using the Public Key provided by the plugin/theme developers' server. |
|
265 | - * |
|
266 | - * @since 1.0.0 |
|
267 | - * |
|
268 | - * @uses \sodium_crypto_box_keypair_from_secretkey_and_publickey() to generate key. |
|
269 | - * @uses \sodium_crypto_secretbox() to encrypt. |
|
270 | - * |
|
271 | - * @param string $data Data to encrypt. |
|
272 | - * @param string $nonce The nonce generated for this encryption. |
|
273 | - * @param string $alice_secret_key The key to use when generating the encryption key. |
|
274 | - * |
|
275 | - * @return string|WP_Error Encrypted envelope or WP_Error on failure. |
|
276 | - */ |
|
277 | - public function encrypt($data, $nonce, $alice_secret_key) |
|
278 | - { |
|
279 | - if (empty($data)) { |
|
280 | - return new WP_Error('no_data', 'No data provided.'); |
|
281 | - } |
|
282 | - |
|
283 | - if (!function_exists('sodium_crypto_secretbox')) { |
|
284 | - return new WP_Error('sodium_crypto_secretbox_not_available', 'lib_sodium not available'); |
|
285 | - } |
|
286 | - |
|
287 | - $bob_public_key = $this->get_vendor_public_key(); |
|
288 | - |
|
289 | - if (is_wp_error($bob_public_key)) { |
|
290 | - return $bob_public_key; |
|
291 | - } |
|
292 | - |
|
293 | - try { |
|
294 | - $alice_to_bob_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey($alice_secret_key, \sodium_hex2bin($bob_public_key)); |
|
295 | - $encrypted = sodium_crypto_box($data, $nonce, $alice_to_bob_kp); |
|
296 | - } catch (\SodiumException $e) { |
|
297 | - return new WP_Error( |
|
298 | - 'encryption_failed_cryptobox', |
|
299 | - sprintf('Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode()) |
|
300 | - ); |
|
301 | - } catch (\RangeException $e) { |
|
302 | - return new WP_Error( |
|
303 | - 'encryption_failed_cryptobox_rangeexception', |
|
304 | - sprintf('Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode()) |
|
305 | - ); |
|
306 | - } catch (\TypeError $e) { |
|
307 | - return new WP_Error( |
|
308 | - 'encryption_failed_cryptobox_typeerror', |
|
309 | - sprintf('Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode()) |
|
310 | - ); |
|
311 | - } |
|
312 | - |
|
313 | - return base64_encode($encrypted); |
|
314 | - } |
|
315 | - |
|
316 | - /** |
|
317 | - * Gets and returns a random nonce. |
|
318 | - * |
|
319 | - * @since 1.0.0 |
|
320 | - * |
|
321 | - * @return string|WP_Error Nonce if created, otherwise WP_Error |
|
322 | - */ |
|
323 | - public function get_nonce() |
|
324 | - { |
|
325 | - if (!function_exists('random_bytes')) { |
|
326 | - return new WP_Error('missing_function', 'No random_bytes function installed.'); |
|
327 | - } |
|
328 | - |
|
329 | - try { |
|
330 | - $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); |
|
331 | - } catch (\Exception $e) { |
|
332 | - return new WP_Error('encryption_failed_randombytes', sprintf('Unable to generate encryption nonce: %s (%s)', $e->getMessage(), $e->getCode())); |
|
333 | - } |
|
334 | - |
|
335 | - return $nonce; |
|
336 | - } |
|
337 | - |
|
338 | - /** |
|
339 | - * Generate unique Client encryption keys. |
|
340 | - * |
|
341 | - * @since 1.0.0 |
|
342 | - * |
|
343 | - * @uses sodium_crypto_box_keypair() |
|
344 | - * @uses sodium_crypto_box_publickey() |
|
345 | - * @uses sodium_crypto_box_secretkey() |
|
346 | - * |
|
347 | - * @return object|WP_Error $alice_keys or WP_Error if there's any issues. |
|
348 | - * $alice_keys = [ |
|
349 | - * 'publicKey' => (string) The public key. |
|
350 | - * 'privateKey' => (string) The private key. |
|
351 | - * ] |
|
352 | - */ |
|
353 | - public function generate_keys() |
|
354 | - { |
|
355 | - if (!function_exists('sodium_crypto_box_keypair')) { |
|
356 | - return new WP_Error('sodium_crypto_secretbox_not_available', 'lib_sodium not available'); |
|
357 | - } |
|
358 | - |
|
359 | - // In our build Alice = Client & Bob = Vendor. |
|
360 | - $aliceKeypair = sodium_crypto_box_keypair(); |
|
361 | - |
|
362 | - $alice_keys = [ |
|
363 | - 'publicKey' => sodium_crypto_box_publickey($aliceKeypair), |
|
364 | - 'privateKey' => sodium_crypto_box_secretkey($aliceKeypair), |
|
365 | - ]; |
|
366 | - |
|
367 | - return (object) $alice_keys; |
|
368 | - } |
|
25 | + /** |
|
26 | + * @var Config |
|
27 | + */ |
|
28 | + private $config; |
|
29 | + |
|
30 | + /** |
|
31 | + * @var Remote |
|
32 | + */ |
|
33 | + private $remote; |
|
34 | + |
|
35 | + /** |
|
36 | + * @var Logging |
|
37 | + */ |
|
38 | + private $logging; |
|
39 | + |
|
40 | + /** |
|
41 | + * @var string Where the plugin should store the public key for encrypting data |
|
42 | + * |
|
43 | + * @since 1.0.0 |
|
44 | + */ |
|
45 | + private $vendor_public_key_option; |
|
46 | + |
|
47 | + /** |
|
48 | + * @var string Endpoint path to Vendor public key. |
|
49 | + */ |
|
50 | + private $vendor_public_key_endpoint = 'wp-json/trustedlogin/v1/public_key'; |
|
51 | + |
|
52 | + /** |
|
53 | + * Encryption constructor. |
|
54 | + * |
|
55 | + * @param Config $config |
|
56 | + * @param Remote $remote |
|
57 | + * @param Logging $logging |
|
58 | + */ |
|
59 | + public function __construct(Config $config, Remote $remote, Logging $logging) |
|
60 | + { |
|
61 | + $this->config = $config; |
|
62 | + $this->remote = $remote; |
|
63 | + $this->logging = $logging; |
|
64 | + |
|
65 | + /** |
|
66 | + * Filter: Sets the site option name for the Public Key for encryption functions. |
|
67 | + * |
|
68 | + * @since 1.0.0 |
|
69 | + * |
|
70 | + * @param string $vendor_public_key_option |
|
71 | + * @param Config $config |
|
72 | + */ |
|
73 | + $this->vendor_public_key_option = apply_filters( |
|
74 | + 'trustedlogin/'.$this->config->ns().'/options/vendor_public_key', |
|
75 | + 'tl_'.$this->config->ns().'_vendor_public_key', |
|
76 | + $this->config |
|
77 | + ); |
|
78 | + } |
|
79 | + |
|
80 | + /** |
|
81 | + * Generates a random hash 64 characters long. |
|
82 | + * |
|
83 | + * If random_bytes() and openssl_random_pseudo_bytes() don't exist, returns WP_Error with code generate_hash_failed. |
|
84 | + * |
|
85 | + * If random_bytes() does not exist and openssl_random_pseudo_bytes() is unable to return a strong result, |
|
86 | + * returns a WP_Error with code `openssl_not_strong_crypto`. |
|
87 | + * |
|
88 | + * @uses random_bytes |
|
89 | + * @uses openssl_random_pseudo_bytes Only used if random_bytes() does not exist. |
|
90 | + * |
|
91 | + * @param Logging The logging object to use |
|
92 | + * |
|
93 | + * @return string|WP_Error 64-character random hash or a WP_Error object explaining what went wrong. See docblock. |
|
94 | + */ |
|
95 | + public static function get_random_hash($logging) |
|
96 | + { |
|
97 | + $byte_length = 64; |
|
98 | + |
|
99 | + $hash = false; |
|
100 | + |
|
101 | + if (function_exists('random_bytes')) { |
|
102 | + try { |
|
103 | + $bytes = random_bytes($byte_length); |
|
104 | + $hash = bin2hex($bytes); |
|
105 | + } catch (\TypeError $e) { |
|
106 | + $logging->log($e->getMessage(), __METHOD__, 'error'); |
|
107 | + } catch (\Error $e) { |
|
108 | + $logging->log($e->getMessage(), __METHOD__, 'error'); |
|
109 | + } catch (\Exception $e) { |
|
110 | + $logging->log($e->getMessage(), __METHOD__, 'error'); |
|
111 | + } |
|
112 | + } else { |
|
113 | + $logging->log('This site does not have the random_bytes() function.', __METHOD__, 'debug'); |
|
114 | + } |
|
115 | + |
|
116 | + if ($hash) { |
|
117 | + return $hash; |
|
118 | + } |
|
119 | + |
|
120 | + if (!function_exists('openssl_random_pseudo_bytes')) { |
|
121 | + return new WP_Error('generate_hash_failed', 'Could not generate a secure hash with random_bytes or openssl.'); |
|
122 | + } |
|
123 | + |
|
124 | + $crypto_strong = false; |
|
125 | + $hash = openssl_random_pseudo_bytes($byte_length, $crypto_strong); |
|
126 | + |
|
127 | + if (!$crypto_strong) { |
|
128 | + return new WP_Error('openssl_not_strong_crypto', 'Site could not generate a secure hash with OpenSSL.'); |
|
129 | + } |
|
130 | + |
|
131 | + return $hash; |
|
132 | + } |
|
133 | + |
|
134 | + /** |
|
135 | + * @param $string |
|
136 | + * |
|
137 | + * @return string|WP_Error |
|
138 | + */ |
|
139 | + public static function hash($string, $length = 16) |
|
140 | + { |
|
141 | + if (!function_exists('sodium_crypto_generichash')) { |
|
142 | + return new WP_Error('sodium_crypto_generichash_not_available', 'sodium_crypto_generichash not available'); |
|
143 | + } |
|
144 | + |
|
145 | + try { |
|
146 | + $hash_bin = sodium_crypto_generichash($string, '', (int) $length); |
|
147 | + $hash = sodium_bin2hex($hash_bin); |
|
148 | + } catch (\TypeError $e) { |
|
149 | + return new WP_Error( |
|
150 | + 'encryption_failed_generichash_typeerror', |
|
151 | + sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
152 | + ); |
|
153 | + } catch (\Error $e) { |
|
154 | + return new WP_Error( |
|
155 | + 'encryption_failed_generichash_error', |
|
156 | + sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
157 | + ); |
|
158 | + } catch (\SodiumException $e) { |
|
159 | + return new WP_Error( |
|
160 | + 'encryption_failed_generichash_sodium', |
|
161 | + sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
162 | + ); |
|
163 | + } catch (\Exception $e) { |
|
164 | + return new WP_Error( |
|
165 | + 'encryption_failed_generichash', |
|
166 | + sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
167 | + ); |
|
168 | + } |
|
169 | + |
|
170 | + return $hash; |
|
171 | + } |
|
172 | + |
|
173 | + /** |
|
174 | + * Fetches the Public Key from local or db. |
|
175 | + * |
|
176 | + * @since 1.0.0 |
|
177 | + * |
|
178 | + * @return string|WP_Error If found, it returns the publicKey, if not a WP_Error |
|
179 | + */ |
|
180 | + public function get_vendor_public_key() |
|
181 | + { |
|
182 | + |
|
183 | + // Already stored as transient |
|
184 | + $public_key = get_site_transient($this->vendor_public_key_option); |
|
185 | + |
|
186 | + if ($public_key) { |
|
187 | + // Documented below |
|
188 | + return apply_filters('trustedlogin/'.$this->config->ns().'/vendor_public_key', $public_key, $this->config); |
|
189 | + } |
|
190 | + |
|
191 | + // Fetch a key from Vendor site |
|
192 | + $remote_key = $this->get_remote_encryption_key(); |
|
193 | + |
|
194 | + if (is_wp_error($remote_key)) { |
|
195 | + $this->logging->log(sprintf('(%s) %s', $remote_key->get_error_code(), $remote_key->get_error_message()), __METHOD__, 'notice'); |
|
196 | + |
|
197 | + return $remote_key; |
|
198 | + } |
|
199 | + |
|
200 | + // Attempt to store Vendor public key in the DB for ten minutes (may be overridden by caching plugins) |
|
201 | + $saved = set_site_transient($this->vendor_public_key_option, $remote_key, 60 * 10); |
|
202 | + |
|
203 | + if (!$saved) { |
|
204 | + $this->logging->log('Public key not saved after being fetched remotely.', __METHOD__, 'warning'); |
|
205 | + } |
|
206 | + |
|
207 | + /** |
|
208 | + * Filter: Override the public key functions. |
|
209 | + * |
|
210 | + * @since 1.0.0 |
|
211 | + * |
|
212 | + * @param string $vendor_public_key |
|
213 | + * @param Config $config |
|
214 | + */ |
|
215 | + return apply_filters('trustedlogin/'.$this->config->ns().'/vendor_public_key', $remote_key, $this->config); |
|
216 | + } |
|
217 | + |
|
218 | + /** |
|
219 | + * Fetches the Public Key from the `TrustedLogin-vendor` plugin on support website. |
|
220 | + * |
|
221 | + * @since 1.0.0 |
|
222 | + * |
|
223 | + * @return string|WP_Error If successful, will return the Public Key string. Otherwise WP_Error on failure. |
|
224 | + */ |
|
225 | + private function get_remote_encryption_key() |
|
226 | + { |
|
227 | + $vendor_url = $this->config->get_setting('vendor/website'); |
|
228 | + |
|
229 | + /** |
|
230 | + * @param string $key_endpoint Endpoint path on vendor (software vendor's) site |
|
231 | + */ |
|
232 | + $key_endpoint = apply_filters('trustedlogin/'.$this->config->ns().'/vendor/public_key/endpoint', $this->vendor_public_key_endpoint); |
|
233 | + |
|
234 | + $url = trailingslashit($vendor_url).$key_endpoint; |
|
235 | + |
|
236 | + $headers = [ |
|
237 | + 'Accept' => 'application/json', |
|
238 | + 'Content-Type' => 'application/json', |
|
239 | + ]; |
|
240 | + |
|
241 | + $request_options = [ |
|
242 | + 'method' => 'GET', |
|
243 | + 'timeout' => 45, |
|
244 | + 'httpversion' => '1.1', |
|
245 | + 'headers' => $headers, |
|
246 | + ]; |
|
247 | + |
|
248 | + $response = wp_remote_request($url, $request_options); |
|
249 | + |
|
250 | + $response_json = $this->remote->handle_response($response, ['publicKey']); |
|
251 | + |
|
252 | + if (is_wp_error($response_json)) { |
|
253 | + if ('not_found' == $response_json->get_error_code()) { |
|
254 | + return new WP_Error('not_found', __('Encryption key could not be fetched, Vendor site returned 404.', 'gravityview')); |
|
255 | + } |
|
256 | + |
|
257 | + return $response_json; |
|
258 | + } |
|
259 | + |
|
260 | + return $response_json['publicKey']; |
|
261 | + } |
|
262 | + |
|
263 | + /** |
|
264 | + * Encrypts a string using the Public Key provided by the plugin/theme developers' server. |
|
265 | + * |
|
266 | + * @since 1.0.0 |
|
267 | + * |
|
268 | + * @uses \sodium_crypto_box_keypair_from_secretkey_and_publickey() to generate key. |
|
269 | + * @uses \sodium_crypto_secretbox() to encrypt. |
|
270 | + * |
|
271 | + * @param string $data Data to encrypt. |
|
272 | + * @param string $nonce The nonce generated for this encryption. |
|
273 | + * @param string $alice_secret_key The key to use when generating the encryption key. |
|
274 | + * |
|
275 | + * @return string|WP_Error Encrypted envelope or WP_Error on failure. |
|
276 | + */ |
|
277 | + public function encrypt($data, $nonce, $alice_secret_key) |
|
278 | + { |
|
279 | + if (empty($data)) { |
|
280 | + return new WP_Error('no_data', 'No data provided.'); |
|
281 | + } |
|
282 | + |
|
283 | + if (!function_exists('sodium_crypto_secretbox')) { |
|
284 | + return new WP_Error('sodium_crypto_secretbox_not_available', 'lib_sodium not available'); |
|
285 | + } |
|
286 | + |
|
287 | + $bob_public_key = $this->get_vendor_public_key(); |
|
288 | + |
|
289 | + if (is_wp_error($bob_public_key)) { |
|
290 | + return $bob_public_key; |
|
291 | + } |
|
292 | + |
|
293 | + try { |
|
294 | + $alice_to_bob_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey($alice_secret_key, \sodium_hex2bin($bob_public_key)); |
|
295 | + $encrypted = sodium_crypto_box($data, $nonce, $alice_to_bob_kp); |
|
296 | + } catch (\SodiumException $e) { |
|
297 | + return new WP_Error( |
|
298 | + 'encryption_failed_cryptobox', |
|
299 | + sprintf('Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode()) |
|
300 | + ); |
|
301 | + } catch (\RangeException $e) { |
|
302 | + return new WP_Error( |
|
303 | + 'encryption_failed_cryptobox_rangeexception', |
|
304 | + sprintf('Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode()) |
|
305 | + ); |
|
306 | + } catch (\TypeError $e) { |
|
307 | + return new WP_Error( |
|
308 | + 'encryption_failed_cryptobox_typeerror', |
|
309 | + sprintf('Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode()) |
|
310 | + ); |
|
311 | + } |
|
312 | + |
|
313 | + return base64_encode($encrypted); |
|
314 | + } |
|
315 | + |
|
316 | + /** |
|
317 | + * Gets and returns a random nonce. |
|
318 | + * |
|
319 | + * @since 1.0.0 |
|
320 | + * |
|
321 | + * @return string|WP_Error Nonce if created, otherwise WP_Error |
|
322 | + */ |
|
323 | + public function get_nonce() |
|
324 | + { |
|
325 | + if (!function_exists('random_bytes')) { |
|
326 | + return new WP_Error('missing_function', 'No random_bytes function installed.'); |
|
327 | + } |
|
328 | + |
|
329 | + try { |
|
330 | + $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); |
|
331 | + } catch (\Exception $e) { |
|
332 | + return new WP_Error('encryption_failed_randombytes', sprintf('Unable to generate encryption nonce: %s (%s)', $e->getMessage(), $e->getCode())); |
|
333 | + } |
|
334 | + |
|
335 | + return $nonce; |
|
336 | + } |
|
337 | + |
|
338 | + /** |
|
339 | + * Generate unique Client encryption keys. |
|
340 | + * |
|
341 | + * @since 1.0.0 |
|
342 | + * |
|
343 | + * @uses sodium_crypto_box_keypair() |
|
344 | + * @uses sodium_crypto_box_publickey() |
|
345 | + * @uses sodium_crypto_box_secretkey() |
|
346 | + * |
|
347 | + * @return object|WP_Error $alice_keys or WP_Error if there's any issues. |
|
348 | + * $alice_keys = [ |
|
349 | + * 'publicKey' => (string) The public key. |
|
350 | + * 'privateKey' => (string) The private key. |
|
351 | + * ] |
|
352 | + */ |
|
353 | + public function generate_keys() |
|
354 | + { |
|
355 | + if (!function_exists('sodium_crypto_box_keypair')) { |
|
356 | + return new WP_Error('sodium_crypto_secretbox_not_available', 'lib_sodium not available'); |
|
357 | + } |
|
358 | + |
|
359 | + // In our build Alice = Client & Bob = Vendor. |
|
360 | + $aliceKeypair = sodium_crypto_box_keypair(); |
|
361 | + |
|
362 | + $alice_keys = [ |
|
363 | + 'publicKey' => sodium_crypto_box_publickey($aliceKeypair), |
|
364 | + 'privateKey' => sodium_crypto_box_secretkey($aliceKeypair), |
|
365 | + ]; |
|
366 | + |
|
367 | + return (object) $alice_keys; |
|
368 | + } |
|
369 | 369 | } |
@@ -13,7 +13,7 @@ discard block |
||
13 | 13 | namespace GravityView\TrustedLogin; |
14 | 14 | |
15 | 15 | // Exit if accessed directly |
16 | -if (!defined('ABSPATH')) { |
|
16 | +if ( ! defined( 'ABSPATH' ) ) { |
|
17 | 17 | exit; |
18 | 18 | } |
19 | 19 | |
@@ -56,7 +56,7 @@ discard block |
||
56 | 56 | * @param Remote $remote |
57 | 57 | * @param Logging $logging |
58 | 58 | */ |
59 | - public function __construct(Config $config, Remote $remote, Logging $logging) |
|
59 | + public function __construct( Config $config, Remote $remote, Logging $logging ) |
|
60 | 60 | { |
61 | 61 | $this->config = $config; |
62 | 62 | $this->remote = $remote; |
@@ -71,8 +71,8 @@ discard block |
||
71 | 71 | * @param Config $config |
72 | 72 | */ |
73 | 73 | $this->vendor_public_key_option = apply_filters( |
74 | - 'trustedlogin/'.$this->config->ns().'/options/vendor_public_key', |
|
75 | - 'tl_'.$this->config->ns().'_vendor_public_key', |
|
74 | + 'trustedlogin/' . $this->config->ns() . '/options/vendor_public_key', |
|
75 | + 'tl_' . $this->config->ns() . '_vendor_public_key', |
|
76 | 76 | $this->config |
77 | 77 | ); |
78 | 78 | } |
@@ -92,40 +92,40 @@ discard block |
||
92 | 92 | * |
93 | 93 | * @return string|WP_Error 64-character random hash or a WP_Error object explaining what went wrong. See docblock. |
94 | 94 | */ |
95 | - public static function get_random_hash($logging) |
|
95 | + public static function get_random_hash( $logging ) |
|
96 | 96 | { |
97 | 97 | $byte_length = 64; |
98 | 98 | |
99 | 99 | $hash = false; |
100 | 100 | |
101 | - if (function_exists('random_bytes')) { |
|
101 | + if ( function_exists( 'random_bytes' ) ) { |
|
102 | 102 | try { |
103 | - $bytes = random_bytes($byte_length); |
|
104 | - $hash = bin2hex($bytes); |
|
105 | - } catch (\TypeError $e) { |
|
106 | - $logging->log($e->getMessage(), __METHOD__, 'error'); |
|
107 | - } catch (\Error $e) { |
|
108 | - $logging->log($e->getMessage(), __METHOD__, 'error'); |
|
109 | - } catch (\Exception $e) { |
|
110 | - $logging->log($e->getMessage(), __METHOD__, 'error'); |
|
103 | + $bytes = random_bytes( $byte_length ); |
|
104 | + $hash = bin2hex( $bytes ); |
|
105 | + } catch ( \TypeError $e ) { |
|
106 | + $logging->log( $e->getMessage(), __METHOD__, 'error' ); |
|
107 | + } catch ( \Error $e ) { |
|
108 | + $logging->log( $e->getMessage(), __METHOD__, 'error' ); |
|
109 | + } catch ( \Exception $e ) { |
|
110 | + $logging->log( $e->getMessage(), __METHOD__, 'error' ); |
|
111 | 111 | } |
112 | 112 | } else { |
113 | - $logging->log('This site does not have the random_bytes() function.', __METHOD__, 'debug'); |
|
113 | + $logging->log( 'This site does not have the random_bytes() function.', __METHOD__, 'debug' ); |
|
114 | 114 | } |
115 | 115 | |
116 | - if ($hash) { |
|
116 | + if ( $hash ) { |
|
117 | 117 | return $hash; |
118 | 118 | } |
119 | 119 | |
120 | - if (!function_exists('openssl_random_pseudo_bytes')) { |
|
121 | - return new WP_Error('generate_hash_failed', 'Could not generate a secure hash with random_bytes or openssl.'); |
|
120 | + if ( ! function_exists( 'openssl_random_pseudo_bytes' ) ) { |
|
121 | + return new WP_Error( 'generate_hash_failed', 'Could not generate a secure hash with random_bytes or openssl.' ); |
|
122 | 122 | } |
123 | 123 | |
124 | 124 | $crypto_strong = false; |
125 | - $hash = openssl_random_pseudo_bytes($byte_length, $crypto_strong); |
|
125 | + $hash = openssl_random_pseudo_bytes( $byte_length, $crypto_strong ); |
|
126 | 126 | |
127 | - if (!$crypto_strong) { |
|
128 | - return new WP_Error('openssl_not_strong_crypto', 'Site could not generate a secure hash with OpenSSL.'); |
|
127 | + if ( ! $crypto_strong ) { |
|
128 | + return new WP_Error( 'openssl_not_strong_crypto', 'Site could not generate a secure hash with OpenSSL.' ); |
|
129 | 129 | } |
130 | 130 | |
131 | 131 | return $hash; |
@@ -136,34 +136,34 @@ discard block |
||
136 | 136 | * |
137 | 137 | * @return string|WP_Error |
138 | 138 | */ |
139 | - public static function hash($string, $length = 16) |
|
139 | + public static function hash( $string, $length = 16 ) |
|
140 | 140 | { |
141 | - if (!function_exists('sodium_crypto_generichash')) { |
|
142 | - return new WP_Error('sodium_crypto_generichash_not_available', 'sodium_crypto_generichash not available'); |
|
141 | + if ( ! function_exists( 'sodium_crypto_generichash' ) ) { |
|
142 | + return new WP_Error( 'sodium_crypto_generichash_not_available', 'sodium_crypto_generichash not available' ); |
|
143 | 143 | } |
144 | 144 | |
145 | 145 | try { |
146 | - $hash_bin = sodium_crypto_generichash($string, '', (int) $length); |
|
147 | - $hash = sodium_bin2hex($hash_bin); |
|
148 | - } catch (\TypeError $e) { |
|
146 | + $hash_bin = sodium_crypto_generichash( $string, '', (int)$length ); |
|
147 | + $hash = sodium_bin2hex( $hash_bin ); |
|
148 | + } catch ( \TypeError $e ) { |
|
149 | 149 | return new WP_Error( |
150 | 150 | 'encryption_failed_generichash_typeerror', |
151 | - sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
151 | + sprintf( 'Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode() ) |
|
152 | 152 | ); |
153 | - } catch (\Error $e) { |
|
153 | + } catch ( \Error $e ) { |
|
154 | 154 | return new WP_Error( |
155 | 155 | 'encryption_failed_generichash_error', |
156 | - sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
156 | + sprintf( 'Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode() ) |
|
157 | 157 | ); |
158 | - } catch (\SodiumException $e) { |
|
158 | + } catch ( \SodiumException $e ) { |
|
159 | 159 | return new WP_Error( |
160 | 160 | 'encryption_failed_generichash_sodium', |
161 | - sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
161 | + sprintf( 'Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode() ) |
|
162 | 162 | ); |
163 | - } catch (\Exception $e) { |
|
163 | + } catch ( \Exception $e ) { |
|
164 | 164 | return new WP_Error( |
165 | 165 | 'encryption_failed_generichash', |
166 | - sprintf('Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode()) |
|
166 | + sprintf( 'Error while generating hash: %s (%s)', $e->getMessage(), $e->getCode() ) |
|
167 | 167 | ); |
168 | 168 | } |
169 | 169 | |
@@ -181,27 +181,27 @@ discard block |
||
181 | 181 | { |
182 | 182 | |
183 | 183 | // Already stored as transient |
184 | - $public_key = get_site_transient($this->vendor_public_key_option); |
|
184 | + $public_key = get_site_transient( $this->vendor_public_key_option ); |
|
185 | 185 | |
186 | - if ($public_key) { |
|
186 | + if ( $public_key ) { |
|
187 | 187 | // Documented below |
188 | - return apply_filters('trustedlogin/'.$this->config->ns().'/vendor_public_key', $public_key, $this->config); |
|
188 | + return apply_filters( 'trustedlogin/' . $this->config->ns() . '/vendor_public_key', $public_key, $this->config ); |
|
189 | 189 | } |
190 | 190 | |
191 | 191 | // Fetch a key from Vendor site |
192 | 192 | $remote_key = $this->get_remote_encryption_key(); |
193 | 193 | |
194 | - if (is_wp_error($remote_key)) { |
|
195 | - $this->logging->log(sprintf('(%s) %s', $remote_key->get_error_code(), $remote_key->get_error_message()), __METHOD__, 'notice'); |
|
194 | + if ( is_wp_error( $remote_key ) ) { |
|
195 | + $this->logging->log( sprintf( '(%s) %s', $remote_key->get_error_code(), $remote_key->get_error_message() ), __METHOD__, 'notice' ); |
|
196 | 196 | |
197 | 197 | return $remote_key; |
198 | 198 | } |
199 | 199 | |
200 | 200 | // Attempt to store Vendor public key in the DB for ten minutes (may be overridden by caching plugins) |
201 | - $saved = set_site_transient($this->vendor_public_key_option, $remote_key, 60 * 10); |
|
201 | + $saved = set_site_transient( $this->vendor_public_key_option, $remote_key, 60 * 10 ); |
|
202 | 202 | |
203 | - if (!$saved) { |
|
204 | - $this->logging->log('Public key not saved after being fetched remotely.', __METHOD__, 'warning'); |
|
203 | + if ( ! $saved ) { |
|
204 | + $this->logging->log( 'Public key not saved after being fetched remotely.', __METHOD__, 'warning' ); |
|
205 | 205 | } |
206 | 206 | |
207 | 207 | /** |
@@ -212,7 +212,7 @@ discard block |
||
212 | 212 | * @param string $vendor_public_key |
213 | 213 | * @param Config $config |
214 | 214 | */ |
215 | - return apply_filters('trustedlogin/'.$this->config->ns().'/vendor_public_key', $remote_key, $this->config); |
|
215 | + return apply_filters( 'trustedlogin/' . $this->config->ns() . '/vendor_public_key', $remote_key, $this->config ); |
|
216 | 216 | } |
217 | 217 | |
218 | 218 | /** |
@@ -224,14 +224,14 @@ discard block |
||
224 | 224 | */ |
225 | 225 | private function get_remote_encryption_key() |
226 | 226 | { |
227 | - $vendor_url = $this->config->get_setting('vendor/website'); |
|
227 | + $vendor_url = $this->config->get_setting( 'vendor/website' ); |
|
228 | 228 | |
229 | 229 | /** |
230 | 230 | * @param string $key_endpoint Endpoint path on vendor (software vendor's) site |
231 | 231 | */ |
232 | - $key_endpoint = apply_filters('trustedlogin/'.$this->config->ns().'/vendor/public_key/endpoint', $this->vendor_public_key_endpoint); |
|
232 | + $key_endpoint = apply_filters( 'trustedlogin/' . $this->config->ns() . '/vendor/public_key/endpoint', $this->vendor_public_key_endpoint ); |
|
233 | 233 | |
234 | - $url = trailingslashit($vendor_url).$key_endpoint; |
|
234 | + $url = trailingslashit( $vendor_url ) . $key_endpoint; |
|
235 | 235 | |
236 | 236 | $headers = [ |
237 | 237 | 'Accept' => 'application/json', |
@@ -245,19 +245,19 @@ discard block |
||
245 | 245 | 'headers' => $headers, |
246 | 246 | ]; |
247 | 247 | |
248 | - $response = wp_remote_request($url, $request_options); |
|
248 | + $response = wp_remote_request( $url, $request_options ); |
|
249 | 249 | |
250 | - $response_json = $this->remote->handle_response($response, ['publicKey']); |
|
250 | + $response_json = $this->remote->handle_response( $response, [ 'publicKey' ] ); |
|
251 | 251 | |
252 | - if (is_wp_error($response_json)) { |
|
253 | - if ('not_found' == $response_json->get_error_code()) { |
|
254 | - return new WP_Error('not_found', __('Encryption key could not be fetched, Vendor site returned 404.', 'gravityview')); |
|
252 | + if ( is_wp_error( $response_json ) ) { |
|
253 | + if ( 'not_found' == $response_json->get_error_code() ) { |
|
254 | + return new WP_Error( 'not_found', __( 'Encryption key could not be fetched, Vendor site returned 404.', 'gravityview' ) ); |
|
255 | 255 | } |
256 | 256 | |
257 | 257 | return $response_json; |
258 | 258 | } |
259 | 259 | |
260 | - return $response_json['publicKey']; |
|
260 | + return $response_json[ 'publicKey' ]; |
|
261 | 261 | } |
262 | 262 | |
263 | 263 | /** |
@@ -274,43 +274,43 @@ discard block |
||
274 | 274 | * |
275 | 275 | * @return string|WP_Error Encrypted envelope or WP_Error on failure. |
276 | 276 | */ |
277 | - public function encrypt($data, $nonce, $alice_secret_key) |
|
277 | + public function encrypt( $data, $nonce, $alice_secret_key ) |
|
278 | 278 | { |
279 | - if (empty($data)) { |
|
280 | - return new WP_Error('no_data', 'No data provided.'); |
|
279 | + if ( empty( $data ) ) { |
|
280 | + return new WP_Error( 'no_data', 'No data provided.' ); |
|
281 | 281 | } |
282 | 282 | |
283 | - if (!function_exists('sodium_crypto_secretbox')) { |
|
284 | - return new WP_Error('sodium_crypto_secretbox_not_available', 'lib_sodium not available'); |
|
283 | + if ( ! function_exists( 'sodium_crypto_secretbox' ) ) { |
|
284 | + return new WP_Error( 'sodium_crypto_secretbox_not_available', 'lib_sodium not available' ); |
|
285 | 285 | } |
286 | 286 | |
287 | 287 | $bob_public_key = $this->get_vendor_public_key(); |
288 | 288 | |
289 | - if (is_wp_error($bob_public_key)) { |
|
289 | + if ( is_wp_error( $bob_public_key ) ) { |
|
290 | 290 | return $bob_public_key; |
291 | 291 | } |
292 | 292 | |
293 | 293 | try { |
294 | - $alice_to_bob_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey($alice_secret_key, \sodium_hex2bin($bob_public_key)); |
|
295 | - $encrypted = sodium_crypto_box($data, $nonce, $alice_to_bob_kp); |
|
296 | - } catch (\SodiumException $e) { |
|
294 | + $alice_to_bob_kp = sodium_crypto_box_keypair_from_secretkey_and_publickey( $alice_secret_key, \sodium_hex2bin( $bob_public_key ) ); |
|
295 | + $encrypted = sodium_crypto_box( $data, $nonce, $alice_to_bob_kp ); |
|
296 | + } catch ( \SodiumException $e ) { |
|
297 | 297 | return new WP_Error( |
298 | 298 | 'encryption_failed_cryptobox', |
299 | - sprintf('Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode()) |
|
299 | + sprintf( 'Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode() ) |
|
300 | 300 | ); |
301 | - } catch (\RangeException $e) { |
|
301 | + } catch ( \RangeException $e ) { |
|
302 | 302 | return new WP_Error( |
303 | 303 | 'encryption_failed_cryptobox_rangeexception', |
304 | - sprintf('Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode()) |
|
304 | + sprintf( 'Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode() ) |
|
305 | 305 | ); |
306 | - } catch (\TypeError $e) { |
|
306 | + } catch ( \TypeError $e ) { |
|
307 | 307 | return new WP_Error( |
308 | 308 | 'encryption_failed_cryptobox_typeerror', |
309 | - sprintf('Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode()) |
|
309 | + sprintf( 'Error while encrypting the envelope: %s (%s)', $e->getMessage(), $e->getCode() ) |
|
310 | 310 | ); |
311 | 311 | } |
312 | 312 | |
313 | - return base64_encode($encrypted); |
|
313 | + return base64_encode( $encrypted ); |
|
314 | 314 | } |
315 | 315 | |
316 | 316 | /** |
@@ -322,14 +322,14 @@ discard block |
||
322 | 322 | */ |
323 | 323 | public function get_nonce() |
324 | 324 | { |
325 | - if (!function_exists('random_bytes')) { |
|
326 | - return new WP_Error('missing_function', 'No random_bytes function installed.'); |
|
325 | + if ( ! function_exists( 'random_bytes' ) ) { |
|
326 | + return new WP_Error( 'missing_function', 'No random_bytes function installed.' ); |
|
327 | 327 | } |
328 | 328 | |
329 | 329 | try { |
330 | - $nonce = random_bytes(SODIUM_CRYPTO_SECRETBOX_NONCEBYTES); |
|
331 | - } catch (\Exception $e) { |
|
332 | - return new WP_Error('encryption_failed_randombytes', sprintf('Unable to generate encryption nonce: %s (%s)', $e->getMessage(), $e->getCode())); |
|
330 | + $nonce = random_bytes( SODIUM_CRYPTO_SECRETBOX_NONCEBYTES ); |
|
331 | + } catch ( \Exception $e ) { |
|
332 | + return new WP_Error( 'encryption_failed_randombytes', sprintf( 'Unable to generate encryption nonce: %s (%s)', $e->getMessage(), $e->getCode() ) ); |
|
333 | 333 | } |
334 | 334 | |
335 | 335 | return $nonce; |
@@ -352,18 +352,18 @@ discard block |
||
352 | 352 | */ |
353 | 353 | public function generate_keys() |
354 | 354 | { |
355 | - if (!function_exists('sodium_crypto_box_keypair')) { |
|
356 | - return new WP_Error('sodium_crypto_secretbox_not_available', 'lib_sodium not available'); |
|
355 | + if ( ! function_exists( 'sodium_crypto_box_keypair' ) ) { |
|
356 | + return new WP_Error( 'sodium_crypto_secretbox_not_available', 'lib_sodium not available' ); |
|
357 | 357 | } |
358 | 358 | |
359 | 359 | // In our build Alice = Client & Bob = Vendor. |
360 | 360 | $aliceKeypair = sodium_crypto_box_keypair(); |
361 | 361 | |
362 | 362 | $alice_keys = [ |
363 | - 'publicKey' => sodium_crypto_box_publickey($aliceKeypair), |
|
364 | - 'privateKey' => sodium_crypto_box_secretkey($aliceKeypair), |
|
363 | + 'publicKey' => sodium_crypto_box_publickey( $aliceKeypair ), |
|
364 | + 'privateKey' => sodium_crypto_box_secretkey( $aliceKeypair ), |
|
365 | 365 | ]; |
366 | 366 | |
367 | - return (object) $alice_keys; |
|
367 | + return (object)$alice_keys; |
|
368 | 368 | } |
369 | 369 | } |
@@ -20,8 +20,7 @@ discard block |
||
20 | 20 | use Sodium; |
21 | 21 | use WP_Error; |
22 | 22 | |
23 | -final class Encryption |
|
24 | -{ |
|
23 | +final class Encryption { |
|
25 | 24 | /** |
26 | 25 | * @var Config |
27 | 26 | */ |
@@ -56,8 +55,7 @@ discard block |
||
56 | 55 | * @param Remote $remote |
57 | 56 | * @param Logging $logging |
58 | 57 | */ |
59 | - public function __construct(Config $config, Remote $remote, Logging $logging) |
|
60 | - { |
|
58 | + public function __construct(Config $config, Remote $remote, Logging $logging) { |
|
61 | 59 | $this->config = $config; |
62 | 60 | $this->remote = $remote; |
63 | 61 | $this->logging = $logging; |
@@ -92,8 +90,7 @@ discard block |
||
92 | 90 | * |
93 | 91 | * @return string|WP_Error 64-character random hash or a WP_Error object explaining what went wrong. See docblock. |
94 | 92 | */ |
95 | - public static function get_random_hash($logging) |
|
96 | - { |
|
93 | + public static function get_random_hash($logging) { |
|
97 | 94 | $byte_length = 64; |
98 | 95 | |
99 | 96 | $hash = false; |
@@ -136,8 +133,7 @@ discard block |
||
136 | 133 | * |
137 | 134 | * @return string|WP_Error |
138 | 135 | */ |
139 | - public static function hash($string, $length = 16) |
|
140 | - { |
|
136 | + public static function hash($string, $length = 16) { |
|
141 | 137 | if (!function_exists('sodium_crypto_generichash')) { |
142 | 138 | return new WP_Error('sodium_crypto_generichash_not_available', 'sodium_crypto_generichash not available'); |
143 | 139 | } |
@@ -177,8 +173,7 @@ discard block |
||
177 | 173 | * |
178 | 174 | * @return string|WP_Error If found, it returns the publicKey, if not a WP_Error |
179 | 175 | */ |
180 | - public function get_vendor_public_key() |
|
181 | - { |
|
176 | + public function get_vendor_public_key() { |
|
182 | 177 | |
183 | 178 | // Already stored as transient |
184 | 179 | $public_key = get_site_transient($this->vendor_public_key_option); |
@@ -222,8 +217,7 @@ discard block |
||
222 | 217 | * |
223 | 218 | * @return string|WP_Error If successful, will return the Public Key string. Otherwise WP_Error on failure. |
224 | 219 | */ |
225 | - private function get_remote_encryption_key() |
|
226 | - { |
|
220 | + private function get_remote_encryption_key() { |
|
227 | 221 | $vendor_url = $this->config->get_setting('vendor/website'); |
228 | 222 | |
229 | 223 | /** |
@@ -274,8 +268,7 @@ discard block |
||
274 | 268 | * |
275 | 269 | * @return string|WP_Error Encrypted envelope or WP_Error on failure. |
276 | 270 | */ |
277 | - public function encrypt($data, $nonce, $alice_secret_key) |
|
278 | - { |
|
271 | + public function encrypt($data, $nonce, $alice_secret_key) { |
|
279 | 272 | if (empty($data)) { |
280 | 273 | return new WP_Error('no_data', 'No data provided.'); |
281 | 274 | } |
@@ -320,8 +313,7 @@ discard block |
||
320 | 313 | * |
321 | 314 | * @return string|WP_Error Nonce if created, otherwise WP_Error |
322 | 315 | */ |
323 | - public function get_nonce() |
|
324 | - { |
|
316 | + public function get_nonce() { |
|
325 | 317 | if (!function_exists('random_bytes')) { |
326 | 318 | return new WP_Error('missing_function', 'No random_bytes function installed.'); |
327 | 319 | } |
@@ -350,8 +342,7 @@ discard block |
||
350 | 342 | * 'privateKey' => (string) The private key. |
351 | 343 | * ] |
352 | 344 | */ |
353 | - public function generate_keys() |
|
354 | - { |
|
345 | + public function generate_keys() { |
|
355 | 346 | if (!function_exists('sodium_crypto_box_keypair')) { |
356 | 347 | return new WP_Error('sodium_crypto_secretbox_not_available', 'lib_sodium not available'); |
357 | 348 | } |