Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
97.67% |
42 / 43 |
|
83.33% |
5 / 6 |
CRAP | |
0.00% |
0 / 1 |
Authenticator | |
97.67% |
42 / 43 |
|
83.33% |
5 / 6 |
15 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
authenticate | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
register | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
6 | |||
set_auth_cookies | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
maybe_create_username | |
85.71% |
6 / 7 |
|
0.00% |
0 / 1 |
3.03 | |||
can_register_with_email | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * Authenticator class. |
4 | * |
5 | * This will authenticate the user. Also responsible for registration |
6 | * in case it is enabled in the settings. |
7 | * |
8 | * @package RtCamp\GoogleLogin |
9 | * @since 1.1.1 |
10 | */ |
11 | |
12 | declare(strict_types=1); |
13 | |
14 | namespace RtCamp\GoogleLogin\Utils; |
15 | |
16 | use WP_User; |
17 | use stdClass; |
18 | use Exception; |
19 | use Throwable; |
20 | use InvalidArgumentException; |
21 | use RtCamp\GoogleLogin\Modules\Settings; |
22 | |
23 | /** |
24 | * Class Authenticator |
25 | * |
26 | * @package RtCamp\GoogleLogin\Utils |
27 | */ |
28 | class Authenticator { |
29 | /** |
30 | * Settings instance. |
31 | * |
32 | * @var Settings |
33 | */ |
34 | private $settings; |
35 | |
36 | /** |
37 | * Authenticator constructor. |
38 | * |
39 | * @param Settings $settings Settings instance. |
40 | */ |
41 | public function __construct( Settings $settings ) { |
42 | $this->settings = $settings; |
43 | } |
44 | |
45 | /** |
46 | * Authenticate the user. |
47 | * |
48 | * If registration setting is on, user will be created if |
49 | * that user does not exist in the application. |
50 | * |
51 | * @param stdClass $user User data object returned by Google. |
52 | * |
53 | * @return WP_User |
54 | * @throws InvalidArgumentException For invalid registrations. |
55 | */ |
56 | public function authenticate( stdClass $user ): WP_User { |
57 | if ( ! property_exists( $user, 'email' ) ) { |
58 | throw new InvalidArgumentException( __( 'Email needs to be present for the user.', 'login-with-google' ) ); |
59 | } |
60 | |
61 | if ( email_exists( $user->email ) ) { |
62 | $user_wp = get_user_by( 'email', $user->email ); |
63 | |
64 | /** |
65 | * Fires once the user has been authenticated. |
66 | * |
67 | * @since 1.3.0 |
68 | * |
69 | * @param WP_User $user_wp WP User data object. |
70 | * @param stdClass $user User data object returned by Google. |
71 | */ |
72 | do_action( 'rtcamp.google_user_logged_in', $user_wp, $user ); |
73 | |
74 | return $user_wp; |
75 | } |
76 | |
77 | /** |
78 | * Check if we need to register the user. |
79 | * |
80 | * @param stdClass $user User object from google. |
81 | * @since 1.0.0 |
82 | */ |
83 | return apply_filters( 'rtcamp.google_register_user', $this->maybe_create_username( $user ) ); |
84 | } |
85 | |
86 | /** |
87 | * Register the new user if setting is on for registration. |
88 | * |
89 | * @param stdClass $user User object from google. |
90 | * |
91 | * @return WP_User|null |
92 | * @throws Throwable Invalid email registration. |
93 | * @throws Exception Registration is off. |
94 | */ |
95 | public function register( stdClass $user ): ?WP_User { |
96 | $register = true === (bool) $this->settings->registration_enabled || (bool) get_option( 'users_can_register', false ); |
97 | |
98 | if ( ! $register ) { |
99 | throw new Exception( __( 'Registration is not allowed.', 'login-with-google' ) ); |
100 | } |
101 | |
102 | try { |
103 | $whitelisted_domains = $this->settings->whitelisted_domains; |
104 | if ( empty( $whitelisted_domains ) || $this->can_register_with_email( $user->email ) ) { |
105 | $uid = wp_insert_user( |
106 | [ |
107 | 'user_login' => Helper::unique_username( $user->login ), |
108 | 'user_pass' => wp_generate_password( 18 ), |
109 | 'user_email' => $user->email, |
110 | 'first_name' => $user->given_name ?? '', |
111 | 'last_name' => $user->family_name ?? '', |
112 | ] |
113 | ); |
114 | |
115 | /** |
116 | * Fires once the user has been registered successfully. |
117 | */ |
118 | do_action( 'rtcamp.google_user_created', $uid, $user ); |
119 | |
120 | return get_user_by( 'id', $uid ); |
121 | } |
122 | |
123 | /* translators: %s is replaced with email ID of user trying to register */ |
124 | throw new Exception( sprintf( __( 'Cannot register with this email: %s', 'login-with-google' ), $user->email ) ); |
125 | |
126 | } catch ( Throwable $e ) { |
127 | |
128 | throw $e; |
129 | } |
130 | |
131 | } |
132 | |
133 | /** |
134 | * Set auth cookies for WordPress login. |
135 | * |
136 | * @param WP_User $user WP User object. |
137 | * |
138 | * @return void |
139 | */ |
140 | public function set_auth_cookies( WP_User $user ) { |
141 | wp_clear_auth_cookie(); |
142 | wp_set_current_user( $user->ID, $user->user_login ); |
143 | wp_set_auth_cookie( $user->ID ); |
144 | } |
145 | |
146 | /** |
147 | * Assign the `login` property to user object |
148 | * if it doesn't exists. |
149 | * |
150 | * @param stdClass $user User object. |
151 | * |
152 | * @return stdClass |
153 | */ |
154 | private function maybe_create_username( stdClass $user ): stdClass { |
155 | if ( property_exists( $user, 'login' ) || ! property_exists( $user, 'email' ) ) { |
156 | return $user; |
157 | } |
158 | |
159 | $email = $user->email; |
160 | $user_login = sanitize_user( current( explode( '@', $email ) ), true ); |
161 | $user_login = Helper::unique_username( $user_login ); |
162 | $user->login = $user_login; |
163 | |
164 | return $user; |
165 | } |
166 | |
167 | /** |
168 | * Check if given email can be used for registration. |
169 | * |
170 | * @param string $email Email ID. |
171 | * |
172 | * @return bool |
173 | */ |
174 | private function can_register_with_email( string $email ): bool { |
175 | $whitelisted_domains = explode( ',', $this->settings->whitelisted_domains ); |
176 | $whitelisted_domains = array_map( 'strtolower', $whitelisted_domains ); |
177 | $whitelisted_domains = array_map( 'trim', $whitelisted_domains ); |
178 | $email_parts = explode( '@', $email ); |
179 | $email_parts = array_map( 'strtolower', $email_parts ); |
180 | |
181 | return in_array( $email_parts[1], $whitelisted_domains, true ); |
182 | } |
183 | } |