Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
97.50% |
39 / 40 |
|
83.33% |
5 / 6 |
CRAP | |
0.00% |
0 / 1 |
| Authenticator | |
97.50% |
39 / 40 |
|
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% |
16 / 16 |
|
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 | } |