PluginProbe
Gianism / trunk
Gianism vtrunk
4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.4.0 5.0.0 5.0.1 5.0.2 5.1.0 5.2.1 5.2.2 5.3.0 6.0.0 6.0.1 trunk 1.0 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 All 65 releases
gianism / app / Gianism / Service / Google.php

Google.php in Gianism trunk, at app/Gianism/Service/Google.php

382 lines 9.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Gianism\Service;
4
5 use Gianism\Cron\Daily;
6
7 /**
8 * Google client
9 *
10 * @package Gianism
11 * @since 2.0.0
12 * @author Takahashi Fumiki
13 *
14 * @property-read \Google_Client $api
15 *
16 */
17 class Google extends AbstractService {
18
19 /**
20 * @depreacted Google stop Google plus.
21 * @var null Google Plus Client.
22 */
23 public $plus = null;
24
25 /**
26 * URL prefix to prepend
27 *
28 * @var string
29 */
30 public $url_prefix = 'google-auth';
31
32 /**
33 * Verbose service name
34 *
35 * @var string
36 */
37 public $verbose_service_name = 'Google';
38
39 /**
40 * @var bool
41 */
42 public $ggl_enabled = false;
43
44 /**
45 * @var string
46 */
47 public $ggl_consumer_key = '';
48
49 /**
50 * @var string
51 */
52 public $ggl_consumer_secret = '';
53
54 /**
55 * @var bool
56 */
57 public $ggl_use_analytics = true;
58
59 /**
60 * @var bool
61 */
62 public $ggl_workspace_mode = false;
63
64 /**
65 * @var string
66 */
67 public $ggl_workspace_allowed_domains = '';
68
69 /**
70 * @var string
71 */
72 public $umeta_account = '_wpg_google_account';
73
74 /**
75 * @var string
76 */
77 public $umeta_plus = '_wpg_google_plus_id';
78
79 /**
80 * Oauth client store
81 *
82 * @var \Google_Client
83 */
84 private $_api = null;
85
86 /**
87 * Plus client
88 *
89 * @var \Google_Service_Plus
90 */
91 private $_plus = null;
92
93 /**
94 * Option to retrieve
95 *
96 * @var array
97 */
98 protected $option_keys = [
99 'ggl_enabled' => false,
100 'ggl_consumer_key' => '',
101 'ggl_consumer_secret' => '',
102 'ggl_use_analytics' => true,
103 'ggl_workspace_mode' => false,
104 'ggl_workspace_allowed_domains' => '',
105 ];
106
107 /**
108 * Constructor
109 *
110 * @param array $argument
111 */
112 protected function __construct( array $argument = [] ) {
113 parent::__construct( $argument );
114 // Filter rewrite name
115 add_filter(
116 'gianism_filter_service_prefix',
117 function ( $prefix ) {
118 if ( 'google-auth' === $prefix ) {
119 $prefix = 'google';
120 }
121 return $prefix;
122 }
123 );
124 }
125
126 /**
127 * Handle callback request
128 *
129 * @global \wpdb $wpdb
130 *
131 * @param string $action
132 *
133 * @return void
134 */
135 protected function handle_default( $action ) {
136 // Get common values
137 $redirect_url = $this->session->get( 'redirect_to' );
138 $code = $this->input->request( 'code' );
139 switch ( $action ) {
140 case 'login': // Let user login
141 try {
142 // Authenticate and get token
143 $token = $this->api->fetchAccessTokenWithAuthCode( $code );
144 $profile = $this->get_profile();
145 // Check email validity
146 if ( ! isset( $profile['email'] ) || ! is_email( $profile['email'] ) ) {
147 throw new \Exception( $this->mail_fail_string() );
148 }
149 $email = $profile['email'];
150 /**
151 * Filter to allow or deny Google login.
152 *
153 * Return false to reject the login.
154 *
155 * @since 5.4.0
156 * @param bool $allowed Whether login is allowed. Default true.
157 * @param string $email User's email address.
158 * @param \Google_Service_Oauth2_Userinfoplus $profile User's profile data from Google.
159 */
160 $allowed = apply_filters( 'gianism_google_login_allowed', true, $email, $profile );
161 if ( ! $allowed ) {
162 throw new \Exception( __( 'You are not allowed to login to this site.', 'wp-gianism' ) );
163 }
164 $plus_id = isset( $profile['id'] ) ? $profile['id'] : 0;
165 $user_id = $this->get_meta_owner( $this->umeta_account, $email );
166 if ( ! $user_id ) {
167 // Test
168 $this->test_user_can_register();
169 // Check email
170 if ( email_exists( $email ) ) {
171 throw new \Exception( $this->duplicate_account_string() );
172 }
173 // Create user name
174 $user_name = $this->valid_username_from_mail( $email );
175 /**
176 * @see Facebook
177 */
178 $user_name = apply_filters( 'gianism_register_name', $user_name, $this->service, $profile );
179 // Create user
180 $user_id = wp_create_user( $user_name, wp_generate_password(), $email );
181 if ( is_wp_error( $user_id ) ) {
182 throw new \Exception( $this->registration_error_string() );
183 }
184 // Update user meta
185 update_user_meta( $user_id, $this->umeta_account, $email );
186 if ( $plus_id ) {
187 update_user_meta( $user_id, $this->umeta_plus, $plus_id );
188 }
189 update_user_meta( $user_id, 'nickname', sanitize_text_field( $profile['name'] ) );
190 $this->db->update(
191 $this->db->users,
192 array(
193 'display_name' => sanitize_text_field( $profile['name'] ),
194 ),
195 array(
196 'ID' => $user_id,
197 ),
198 array( '%s' ),
199 array( '%d' )
200 );
201 $this->user_password_unknown( $user_id );
202 $this->hook_connect( $user_id, $profile, true );
203 $this->welcome( $profile['name'] );
204 }
205 // Make user logged in
206 $this->set_auth_cookie( $user_id );
207 $redirect_url = $this->filter_redirect( $redirect_url, 'login' );
208 } catch ( \Exception $e ) {
209 $this->auth_fail( $e->getMessage() );
210 $redirect_url = wp_login_url( $redirect_url, true );
211 $redirect_url = $this->filter_redirect( $redirect_url, 'login-failure' );
212 }
213 wp_redirect( $redirect_url );
214 exit;
215 break;
216 case 'connect': // Connect account
217 // Connection finished. Let's redirect.
218 if ( ! $redirect_url ) {
219 $redirect_url = admin_url( 'profile.php' );
220 }
221 try {
222 // Authenticate and get token
223 $token = $this->api->fetchAccessTokenWithAuthCode( $code );
224 $profile = $this->get_profile();
225 // Check email validity
226 if ( ! isset( $profile['email'] ) || ! is_email( $profile['email'] ) ) {
227 throw new \Exception( $this->mail_fail_string() );
228 }
229 // Check if other user has these as meta_value
230 $email = $profile['email'];
231 /** This filter is documented in app/Gianism/Service/Google.php */
232 $allowed = apply_filters( 'gianism_google_login_allowed', true, $email, $profile );
233 if ( ! $allowed ) {
234 throw new \Exception( __( 'You are not allowed to connect this account.', 'wp-gianism' ) );
235 }
236 $email_owner = $this->get_meta_owner( $this->umeta_account, $email );
237 if ( $email_owner && ( get_current_user_id() !== $email_owner ) ) {
238 throw new \Exception( $this->duplicate_account_string() );
239 }
240 // Now let's save user data
241 update_user_meta( get_current_user_id(), $this->umeta_account, $email );
242 if ( isset( $profile['id'] ) && $profile['id'] ) {
243 update_user_meta( get_current_user_id(), $this->umeta_plus, $profile['id'] );
244 }
245 // Fires hook
246 $this->hook_connect( get_current_user_id(), $profile );
247 // Save message
248 $this->welcome( $profile['name'] );
249 // Apply filter
250 $redirect_url = $this->filter_redirect( $redirect_url, 'connect' );
251 } catch ( \Exception $e ) {
252 $this->auth_fail( $e->getMessage() );
253 // Apply filter
254 $redirect_url = $this->filter_redirect( $redirect_url, 'connect-failure' );
255 }
256 // Connection finished. Let's redirect.
257 if ( ! $redirect_url ) {
258 $redirect_url = admin_url( 'profile.php' );
259 }
260 wp_redirect( $redirect_url );
261 exit;
262 break;
263 default:
264 /**
265 * @see Facebook
266 */
267 do_action(
268 'gianism_extra_action',
269 $this->service_name,
270 $action,
271 [
272 'redirect_to' => $redirect_url,
273 'code' => $code,
274 ]
275 );
276 $this->input->wp_die( sprintf( $this->_( 'Sorry, but wrong access. Please go back to <a href="%s">%s</a>.' ), home_url( '/' ), get_bloginfo( 'name' ) ), 500, false );
277 break;
278 }
279 }
280
281
282 /**
283 * Returns Profile
284 *
285 * @depreacted Google stop Google Plus
286 * @return \Google_Service_Oauth2_Userinfoplus
287 */
288 private function get_profile() {
289 $oauth = new \Google_Service_Oauth2( $this->api );
290 return $oauth->userinfo->get();
291 }
292
293 /**
294 * Detect if user is connected to this service
295 *
296 * @param int $user_id
297 *
298 * @return bool
299 */
300 public function is_connected( $user_id ) {
301 return (bool) get_user_meta( $user_id, $this->umeta_account, true );
302 }
303
304 /**
305 * Disconnect user from this service
306 *
307 * @param int $user_id
308 *
309 * @return mixed
310 */
311 public function disconnect( $user_id ) {
312 delete_user_meta( $user_id, $this->umeta_account );
313 delete_user_meta( $user_id, $this->umeta_plus );
314 }
315
316 /**
317 * Return api URL to authenticate
318 *
319 * If you need additional information (ex. token),
320 * use $this->session->write inside.
321 *
322 * <code>
323 * $this->session->write('token', $token);
324 * return $url;
325 * </code>
326 *
327 * @param string $action 'connect', 'login'
328 *
329 * @return string|false URL to redirect
330 * @throws \Exception
331 */
332 protected function get_api_url( $action ) {
333 switch ( $action ) {
334 case 'login':
335 case 'connect':
336 return $this->api->createAuthUrl();
337 default:
338 return false;
339 }
340 }
341
342 protected function login_label( $register = false, $context = '' ) {
343 // translators: %s is service name.
344 return sprintf( _x( 'Sign in with %s', 'login label', 'wp-gianism' ), $this->verbose_service_name );
345 }
346
347 protected function svg_path() {
348 return 'google.png';
349 }
350
351 /**
352 * Getter
353 *
354 * @param string $name
355 *
356 * @return mixed
357 */
358 public function __get( $name ) {
359 switch ( $name ) {
360 case 'api':
361 if ( ! $this->_api ) {
362 $this->_api = new \Google_Client();
363 $this->_api->setApplicationName( get_bloginfo( 'name' ) );
364 $this->_api->setClientId( $this->ggl_consumer_key );
365 $this->_api->setClientSecret( $this->ggl_consumer_secret );
366 $this->_api->setRedirectUri( $this->get_redirect_endpoint() );
367 $this->_api->setApprovalPrompt( 'auto' );
368 $this->_api->setAccessType( 'online' );
369 $this->_api->setScopes(
370 [
371 'https://www.googleapis.com/auth/userinfo.profile',
372 'https://www.googleapis.com/auth/userinfo.email',
373 ]
374 );
375 }
376 return $this->_api;
377 default:
378 return parent::__get( $name );
379 }
380 }
381 }
382