Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
82.87% |
150 / 181 |
|
75.00% |
12 / 16 |
CRAP | |
0.00% |
0 / 1 |
Settings | |
82.87% |
150 / 181 |
|
75.00% |
12 / 16 |
35.83 | |
0.00% |
0 / 1 |
__get | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
name | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
init | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
modify_cookie_expiry | |
90.91% |
10 / 11 |
|
0.00% |
0 / 1 |
7.04 | |||
register_settings | |
100.00% |
70 / 70 |
|
100.00% |
1 / 1 |
1 | |||
get_warning_classes | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
cookie_expiry_field | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
2 | |||
client_id_field | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
1 | |||
client_secret_field | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
user_registration | |
100.00% |
15 / 15 |
|
100.00% |
1 / 1 |
2 | |||
one_tap_login | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
one_tap_login_screens | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
2 | |||
whitelisted_domains | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
settings_page | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
output | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
disabled | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | /** |
3 | * Register the settings under settings page and also |
4 | * provide the interface to retrieve the settings. |
5 | * |
6 | * @package RtCamp\GoogleLogin |
7 | * @since 1.0.0 |
8 | * @author rtCamp <contact@rtcamp.com> |
9 | */ |
10 | |
11 | declare(strict_types=1); |
12 | |
13 | namespace RtCamp\GoogleLogin\Modules; |
14 | |
15 | use RtCamp\GoogleLogin\Interfaces\Module as ModuleInterface; |
16 | |
17 | use RtCamp\GoogleLogin\Utils\Helper; |
18 | |
19 | use stdClass; |
20 | |
21 | use function RtCamp\GoogleLogin\plugin; |
22 | |
23 | /** |
24 | * Class Settings. |
25 | * |
26 | * @property string|null whitelisted_domains |
27 | * @property string|null client_id |
28 | * @property string|null client_secret |
29 | * @property bool|null registration_enabled |
30 | * @property bool|null one_tap_login |
31 | * @property string one_tap_login_screen |
32 | * @property int|null cookie_expiry |
33 | * |
34 | * @package RtCamp\GoogleLogin\Modules |
35 | */ |
36 | class Settings implements ModuleInterface { |
37 | |
38 | /** |
39 | * Settings values. |
40 | * |
41 | * @var array |
42 | */ |
43 | public $options; |
44 | |
45 | /** |
46 | * Getters for settings values. |
47 | * |
48 | * @var string[] |
49 | */ |
50 | private $getters = [ |
51 | 'WP_GOOGLE_LOGIN_CLIENT_ID' => 'client_id', |
52 | 'WP_GOOGLE_LOGIN_SECRET' => 'client_secret', |
53 | 'WP_GOOGLE_LOGIN_USER_REGISTRATION' => 'registration_enabled', |
54 | 'WP_GOOGLE_LOGIN_WHITELIST_DOMAINS' => 'whitelisted_domains', |
55 | 'WP_GOOGLE_ONE_TAP_LOGIN' => 'one_tap_login', |
56 | 'WP_GOOGLE_ONE_TAP_LOGIN_SCREEN' => 'one_tap_login_screen', |
57 | 'WP_GOOGLE_COOKIE_EXPIRY' => 'cookie_expiry', |
58 | ]; |
59 | |
60 | /** |
61 | * Getter method. |
62 | * |
63 | * @param string $name Name of option to fetch. |
64 | */ |
65 | public function __get( string $name ) { |
66 | if ( in_array( $name, $this->getters, true ) ) { |
67 | $constant_name = array_search( $name, $this->getters, true ); |
68 | |
69 | return defined( $constant_name ) ? constant( $constant_name ) : ( $this->options[ $name ] ?? '' ); |
70 | } |
71 | |
72 | return null; |
73 | } |
74 | |
75 | /** |
76 | * Return module name. |
77 | * |
78 | * @return string |
79 | */ |
80 | public function name(): string { |
81 | return 'settings'; |
82 | } |
83 | |
84 | /** |
85 | * Initialization of module. |
86 | * |
87 | * @return void |
88 | */ |
89 | public function init(): void { |
90 | $this->options = get_option( 'wp_google_login_settings', [] ); |
91 | add_action( 'admin_init', [ $this, 'register_settings' ] ); |
92 | add_action( 'admin_menu', [ $this, 'settings_page' ] ); |
93 | add_filter( 'auth_cookie_expiration', [ $this, 'modify_cookie_expiry' ] ); |
94 | } |
95 | |
96 | /** |
97 | * Modify cookie expiry. |
98 | * |
99 | * @param int $expiration Current cookie expiry. |
100 | * |
101 | * @return int |
102 | */ |
103 | public function modify_cookie_expiry( int $expiration ): int { |
104 | $state = Helper::filter_input( INPUT_GET, 'state', FILTER_SANITIZE_FULL_SPECIAL_CHARS ); |
105 | |
106 | if ( ! $state ) { |
107 | return $expiration; |
108 | } |
109 | |
110 | $state = base64_decode( $state ); |
111 | $state = $state ? json_decode( $state ) : null; |
112 | |
113 | if ( ! ( $state instanceof stdClass ) || empty( $state->provider ) || 'google' !== $state->provider ) { |
114 | return $expiration; |
115 | } |
116 | |
117 | if ( ! is_numeric( $this->cookie_expiry ) ) { |
118 | return $expiration; |
119 | } |
120 | |
121 | $days = intval( $this->cookie_expiry ); |
122 | |
123 | return $days * DAY_IN_SECONDS; |
124 | } |
125 | |
126 | /** |
127 | * Register the settings, section and fields. |
128 | * |
129 | * @return void |
130 | */ |
131 | public function register_settings(): void { |
132 | register_setting( 'wp_google_login', 'wp_google_login_settings' ); |
133 | |
134 | add_settings_section( |
135 | 'wp_google_login_section', |
136 | __( 'Log in with Google Settings', 'login-with-google' ), |
137 | function () { |
138 | }, |
139 | 'login-with-google' |
140 | ); |
141 | |
142 | add_settings_field( |
143 | 'wp_google_login_client_id', |
144 | __( 'Client ID', 'login-with-google' ), |
145 | [ $this, 'client_id_field' ], |
146 | 'login-with-google', |
147 | 'wp_google_login_section', |
148 | [ 'label_for' => 'client-id' ] |
149 | ); |
150 | |
151 | add_settings_field( |
152 | 'wp_google_login_client_secret', |
153 | __( 'Client Secret', 'login-with-google' ), |
154 | [ $this, 'client_secret_field' ], |
155 | 'login-with-google', |
156 | 'wp_google_login_section', |
157 | [ 'label_for' => 'client-secret' ] |
158 | ); |
159 | |
160 | add_settings_field( |
161 | 'wp_google_allow_registration', |
162 | __( 'Create New User', 'login-with-google' ), |
163 | [ $this, 'user_registration' ], |
164 | 'login-with-google', |
165 | 'wp_google_login_section', |
166 | [ 'label_for' => 'user-registration' ] |
167 | ); |
168 | |
169 | add_settings_field( |
170 | 'wp_google_one_tap_login', |
171 | __( 'Enable One Tap Login', 'login-with-google' ), |
172 | [ $this, 'one_tap_login' ], |
173 | 'login-with-google', |
174 | 'wp_google_login_section', |
175 | [ 'label_for' => 'one-tap-login', ] |
176 | ); |
177 | |
178 | add_settings_field( |
179 | 'wp_google_one_tap_login_screen', |
180 | __( 'One Tap Login Locations', 'login-with-google' ), |
181 | [ $this, 'one_tap_login_screens' ], |
182 | 'login-with-google', |
183 | 'wp_google_login_section', |
184 | [ |
185 | 'label_for' => 'one-tap-login-screen', |
186 | 'class' => 'one-tap-login-screen-row', |
187 | ] |
188 | ); |
189 | |
190 | add_settings_field( |
191 | 'wp_google_whitelisted_domain', |
192 | __( 'Whitelisted Domains', 'login-with-google' ), |
193 | [ $this, 'whitelisted_domains' ], |
194 | 'login-with-google', |
195 | 'wp_google_login_section', |
196 | [ 'label_for' => 'whitelisted-domains' ] |
197 | ); |
198 | |
199 | add_settings_field( |
200 | 'wp_google_cookie_expiry', |
201 | __( 'Auto logout after', 'login-with-google' ), |
202 | [ $this, 'cookie_expiry_field' ], |
203 | 'login-with-google', |
204 | 'wp_google_login_section', |
205 | [ |
206 | 'label_for' => 'cookie-expiry', |
207 | 'class' => 'cookie-expiry-row', |
208 | ] |
209 | ); |
210 | } |
211 | |
212 | /** |
213 | * Get Warning classes. |
214 | * |
215 | * @param int $days Days. |
216 | * |
217 | * @return string |
218 | */ |
219 | private function get_warning_classes( int $days ): string { |
220 | $warning_classes = 'warning'; |
221 | if ( empty( $days ) || $days < 14 ) { |
222 | $warning_classes .= ' hidden'; |
223 | } |
224 | |
225 | return $warning_classes; |
226 | } |
227 | |
228 | /** |
229 | * Render cookie expiry field. |
230 | * |
231 | * @return void |
232 | */ |
233 | public function cookie_expiry_field(): void { |
234 | |
235 | $days = ! is_numeric( $this->cookie_expiry ) ? '' : intval( $this->cookie_expiry ); |
236 | $warning_classes = $this->get_warning_classes( intval( $days ) ); |
237 | |
238 | ?> |
239 | <div class='cookie_expiry_settings_wrapper'> |
240 | <input placeholder="<?php esc_attr_e( 'Number of days, e.g., 12', 'login-with-google' ); ?>" type='number' inputmode='numeric' name='wp_google_login_settings[cookie_expiry]' id='cookie-expiry' value='<?php echo esc_attr( $days ); ?>' autocomplete='off' /> |
241 | </div> |
242 | <p class='description'> |
243 | <?php echo esc_html__( 'The number of days after which the user will be automatically logged out (applicable only for Google login).', 'login-with-google' ); ?> |
244 | </p> |
245 | |
246 | <p class='<?php echo esc_attr( $warning_classes ); ?>'> |
247 | <?php |
248 | echo esc_html__( 'Setting a cookie expiry for more than 14 days can have security implications. Proceed with caution!', 'login-with-google' ); |
249 | ?> |
250 | </p> |
251 | <?php |
252 | } |
253 | |
254 | /** |
255 | * Render client ID field. |
256 | * |
257 | * @return void |
258 | */ |
259 | public function client_id_field(): void { ?> |
260 | <input type='text' name='wp_google_login_settings[client_id]' id="client-id" value='<?php echo esc_attr( $this->client_id ); ?>' autocomplete="off" <?php $this->disabled( 'client_id' ); ?> /> |
261 | <p class="description"> |
262 | <?php |
263 | echo wp_kses_post( |
264 | sprintf( |
265 | '<p>%1s <a target="_blank" href="%2s">%3s</a>.</p>', |
266 | esc_html__( 'Create oAuth Client ID and Client Secret at', 'login-with-google' ), |
267 | 'https://console.developers.google.com/apis/dashboard', |
268 | 'console.developers.google.com' |
269 | ) |
270 | ); |
271 | ?> |
272 | </p> |
273 | <?php |
274 | } |
275 | |
276 | /** |
277 | * Render client secret field. |
278 | * |
279 | * @return void |
280 | */ |
281 | public function client_secret_field(): void { |
282 | ?> |
283 | <input type='password' name='wp_google_login_settings[client_secret]' id="client-secret" value='<?php echo esc_attr( $this->client_secret ); ?>' autocomplete="off" <?php $this->disabled( 'client_secret' ); ?> /> |
284 | <?php |
285 | } |
286 | |
287 | /** |
288 | * User registration field. |
289 | * |
290 | * This will tell us whether or not to create the user |
291 | * if the user does not exist on WP application. |
292 | * |
293 | * This is irrespective of registration flag present in Settings > General |
294 | * |
295 | * @return void |
296 | */ |
297 | public function user_registration(): void { |
298 | ?> |
299 | <label style='display:block;margin-top:6px;'><input <?php $this->disabled( 'registration_enabled' ); ?> type='checkbox' |
300 | name='wp_google_login_settings[registration_enabled]' |
301 | id="user-registration" <?php echo esc_attr( checked( $this->registration_enabled ) ); ?> |
302 | value='1'> |
303 | <?php esc_html_e( 'Create a new user account if it does not exist already', 'login-with-google' ); ?> |
304 | </label> |
305 | <p class="description"> |
306 | <?php |
307 | echo wp_kses_post( |
308 | sprintf( |
309 | /* translators: %1s will be replaced by page link */ |
310 | __( 'If this setting is checked, a new user will be created even if <a target="_blank" href="%1s">membership setting</a> is off.', 'login-with-google' ), |
311 | is_multisite() ? 'network/settings.php' : 'options-general.php' |
312 | ) |
313 | ); |
314 | ?> |
315 | </p> |
316 | <?php |
317 | } |
318 | |
319 | /** |
320 | * Toggle One Tap Login functionality. |
321 | * |
322 | * @return void |
323 | */ |
324 | public function one_tap_login(): void { |
325 | ?> |
326 | <label style='display:block;margin-top:6px;'><input <?php $this->disabled( 'one_tap_login' ); ?> |
327 | type='checkbox' |
328 | name='wp_google_login_settings[one_tap_login]' |
329 | id="one-tap-login" <?php echo esc_attr( checked( $this->one_tap_login ) ); ?> |
330 | value='1'> |
331 | <?php esc_html_e( 'One Tap Login', 'login-with-google' ); ?> |
332 | </label> |
333 | <?php |
334 | } |
335 | |
336 | /** |
337 | * One tap login screens. |
338 | * |
339 | * It can be enabled only for wp-login.php OR sitewide. |
340 | * |
341 | * @return void |
342 | */ |
343 | public function one_tap_login_screens(): void { |
344 | $default = $this->one_tap_login_screen ?? ''; |
345 | ?> |
346 | <label style='display:block;margin-top:6px;'><input <?php $this->disabled( 'one_tap_login' ); ?> |
347 | type='radio' |
348 | name='wp_google_login_settings[one_tap_login_screen]' |
349 | id="one-tap-login-screen-login" <?php echo esc_attr( checked( $this->one_tap_login_screen, $default ) ); ?> |
350 | value='login'> |
351 | <?php esc_html_e( 'Enable One Tap Login Only on Login Screen', 'login-with-google' ); ?> |
352 | </label> |
353 | <label style='display:block;margin-top:6px;'><input <?php $this->disabled( 'one_tap_login' ); ?> |
354 | type='radio' |
355 | name='wp_google_login_settings[one_tap_login_screen]' |
356 | id="one-tap-login-screen-sitewide" <?php echo esc_attr( checked( $this->one_tap_login_screen, 'sitewide' ) ); ?> |
357 | value='sitewide'> |
358 | <?php esc_html_e( 'Enable One Tap Login Site-wide', 'login-with-google' ); ?> |
359 | </label> |
360 | <?php |
361 | } |
362 | |
363 | /** |
364 | * Whitelisted domains for registration. |
365 | * |
366 | * Only emails belonging to these domains would be preferred |
367 | * for registration. |
368 | * |
369 | * If left blank, all domains would be allowed. |
370 | * |
371 | * @return void |
372 | */ |
373 | public function whitelisted_domains(): void { |
374 | ?> |
375 | <input <?php $this->disabled( 'whitelisted_domains' ); ?> type='text' name='wp_google_login_settings[whitelisted_domains]' id="whitelisted-domains" value='<?php echo esc_attr( $this->whitelisted_domains ); ?>' autocomplete="off" /> |
376 | <p class="description"> |
377 | <?php echo esc_html( __( 'Add each domain comma separated', 'login-with-google' ) ); ?> |
378 | </p> |
379 | <?php |
380 | } |
381 | |
382 | /** |
383 | * Add settings sub-menu page in admin menu. |
384 | * |
385 | * @return void |
386 | */ |
387 | public function settings_page(): void { |
388 | add_options_page( |
389 | __( 'Login with Google settings', 'login-with-google' ), |
390 | __( 'Login with Google', 'login-with-google' ), |
391 | 'manage_options', |
392 | 'login-with-google', |
393 | [ $this, 'output' ] |
394 | ); |
395 | } |
396 | |
397 | /** |
398 | * Output the plugin settings. |
399 | * |
400 | * @return void |
401 | */ |
402 | public function output(): void { |
403 | ?> |
404 | <div class="wrap"> |
405 | <form action='options.php' method='post'> |
406 | <?php |
407 | settings_fields( 'wp_google_login' ); |
408 | do_settings_sections( 'login-with-google' ); |
409 | submit_button(); |
410 | ?> |
411 | </form> |
412 | </div> |
413 | <?php |
414 | } |
415 | |
416 | /** |
417 | * Outputs the disabled attribute if field needs to |
418 | * be disabled. |
419 | * |
420 | * @param string $id Input ID. |
421 | * |
422 | * @return void |
423 | */ |
424 | private function disabled( string $id ): void { |
425 | if ( empty( $id ) ) { |
426 | return; |
427 | } |
428 | |
429 | $constant_name = array_search( $id, $this->getters, true ); |
430 | |
431 | if ( false !== $constant_name ) { |
432 | if ( defined( $constant_name ) ) { |
433 | echo esc_attr( 'disabled="disabled"' ); |
434 | } |
435 | } |
436 | } |
437 | } |