PluginProbe ʕ •ᴥ•ʔ
Firebase Authentication / 1.6.1
Firebase Authentication v1.6.1
1.7.0 trunk 1.0.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.8 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9
firebase-authentication / class-mo-firebase-config.php
firebase-authentication Last commit date
admin 3 years ago includes 3 years ago languages 3 years ago public 3 years ago views 3 years ago README.txt 3 years ago class-mo-firebase-config.php 3 years ago class-mo-firebase-contact-us.php 3 years ago firebase-authentication.php 3 years ago index.php 3 years ago uninstall.php 3 years ago
class-mo-firebase-config.php
330 lines
1 <?php
2 /**
3 * File containing Firebase API calls
4 *
5 * @package Firebase Config
6 */
7
8 /**
9 * Class containing Firebase API call functions
10 */
11 class Mo_Firebase_Config {
12 /**
13 * Initializing the test config control
14 */
15 public function __construct() {
16 add_action( 'init', array( $this, 'testconfig' ) );
17 }
18 /**
19 * Test configuration check
20 */
21 public function testconfig() {
22 if ( isset( $_REQUEST['mo_action'] ) && 'firebaselogin' === sanitize_text_field( wp_unslash( $_REQUEST['mo_action'] ) ) && isset( $_REQUEST['test'] ) && 'true' === sanitize_text_field( wp_unslash( $_REQUEST['test'] ) ) && isset( $_REQUEST['mo_firebase_auth_test_config_field'] ) && wp_verify_nonce( sanitize_text_field( wp_unslash( $_REQUEST['mo_firebase_auth_test_config_field'] ) ), 'mo_firebase_auth_test_config_form' ) ) {
23
24 $project_id = get_option( 'mo_firebase_auth_project_id' );
25 $api_key = get_option( 'mo_firebase_auth_api_key' );
26
27 $test_username = isset( $_POST['test_username'] ) ? sanitize_text_field( wp_unslash( $_POST['test_username'] ) ) : '';
28 $test_password = isset( $_POST['test_password'] ) ? sanitize_text_field( wp_unslash( $_POST['test_password'] ) ) : '';
29
30 $response = $this->mo_firebase_authenticate_call( $test_username, $test_password );
31 $response = json_decode( $response, true );
32
33 if ( isset( $response['error'] ) ) {
34 $fb_error = $response['error']['message'];
35 if ( 'INVALID_PASSWORD' === $fb_error ) {
36 $fb_error = 'The password is invalid or the user does not have a password.';
37 } elseif ( 'EMAIL_NOT_FOUND' === $fb_error ) {
38 $fb_error = 'There is no user record corresponding to this identifier. The user may have been deleted.';
39 } elseif ( 'INVALID_EMAIL' === $fb_error ) {
40 $fb_error = 'The email address is badly formatted.';
41 }
42 echo '<div style="font-family:Calibri;padding: 0 30%;">';
43 echo '<h1 style="color:#d9534f;text-align:center;">test failed</h1>';
44 echo '<h4 style="text-align:center;"><b>ERROR :</b>' . esc_attr( $fb_error ) . '</h4>';
45 echo '</div>';
46 echo '<div style="padding: 10px;"></div><div style="position:absolute;padding:0 46%;"><input style="padding:1%;width:100px;height:30px;background: #0091CD none repeat scroll 0% 0%;cursor: pointer;font-size:15px;border-width: 1px;border-style: solid;border-radius: 3px;white-space: nowrap;box-sizing: border-box;border-color: #0073AA;box-shadow: 0px 1px 0px rgba(120, 200, 230, 0.6) inset;color: #FFF;"type="button" value="Close" onClick="self.close();"></div>';
47 exit();
48 } else {
49 $id_token = $response['idToken'];
50 $payload = $this->decode_jwt( $id_token );
51 echo '<div style="font-family:Calibri;margin: auto;padding:5%;">';
52 echo '<h1 style="color:#00C851;text-align:center;">Test Successful !</h1>';
53 echo '<style>table{border-collapse:collapse;}th {background-color: #eee; text-align: center; padding: 8px; border-width:1px; border-style:solid; border-color:#212121;}tr:nth-child(odd) {background-color: #f2f2f2;} td{padding:8px;border-width:1px; border-style:solid; border-color:#212121;}</style>';
54 echo '<h3 style="text-align:center;">Test Configuration</h3><table style="margin: auto;"><tr><th>Attribute Name</th><th>Attribute Value</th></tr>';
55 $this->testattrmappingconfig( '', $payload );
56 echo '</table></div>';
57 echo '<div style="margin: auto;position:absolute;padding:0 40%;"><input style="margin: auto;position:absolute; padding:8px;width:12%;background: #0091CD none repeat scroll 0% 0%;cursor: pointer;font-size:15px;border-width: 1px;border-style: solid;border-radius: 3px;white-space: nowrap;box-sizing: border-box;border-color: #0073AA;box-shadow: 0px 1px 0px rgba(120, 200, 230, 0.6) inset;color: #FFF;"type="button" value="Done" onClick="self.close();"></div>';
58 exit();
59 }
60 }
61 }
62 /**
63 * Processing test configuration
64 *
65 * @param string $nestedprefix .
66 * @param array $payload .
67 */
68 public function testattrmappingconfig( $nestedprefix, $payload ) {
69 foreach ( $payload as $key => $value ) {
70 if ( is_array( $value ) || is_object( $value ) ) {
71 if ( ! empty( $nestedprefix ) ) {
72 $nestedprefix .= '.';
73 }
74 $this->testattrmappingconfig( $nestedprefix . $key, $value );
75 } else {
76 echo '<tr><td>';
77 if ( ! empty( $nestedprefix ) ) {
78 echo esc_attr( $nestedprefix ) . '.';
79 }
80 echo esc_attr( $key ) . '</td><td>' . esc_attr( $value ) . '</td></tr>';
81 }
82 }
83 }
84 /**
85 * Decode JWT token.
86 *
87 * @param string $jwt_token firebase ID token.
88 */
89 public function decode_jwt( $jwt_token ) {
90 $flag = 0;
91 $pieces = explode( '.', $jwt_token );
92 $jwt_data = $pieces[0] . '.' . $pieces[1];
93 $jwt_signature = str_replace( array( '-', '_' ), array( '+', '/' ), $pieces[2] );
94 $jwt_signature = base64_decode( $jwt_signature ); //phpcs:ignore -- ignoring DiscouragedPHPFunctions warning as this line of code is used for decoding JWT signature part.
95 $jwt_header = json_decode( base64_decode( str_replace( array( '-', '_' ), array( '+', '/' ), $pieces[0] ) ), true ); //phpcs:ignore -- ignoring DiscouragedPHPFunctions warning as this line of code is used for decoding JWT header part.
96
97 $alg = $jwt_header['alg'];
98 $kid = $jwt_header['kid'];
99
100 if ( strpos( $alg, 'RS' ) !== false ) {
101 $algorithm = 'RSA';
102 $sha = explode( 'RS', $alg )[1];
103 }
104
105 $jwt_raw_certificate = $this->mo_firebase_auth_get_cert_from_kid( $kid );
106
107 $public_key = '';
108 $parts = explode( '-----', $jwt_raw_certificate );
109
110 if ( preg_match( '/\r\n|\r|\n/', $parts[2] ) ) {
111 $public_key = $jwt_raw_certificate;
112 } else {
113 $encoding = '-----' . $parts[1] . "-----\n";
114 $offset = 0;
115 $segment = substr( $parts[2], $offset, 64 );
116 while ( $segment ) {
117 $encoding .= $segment . "\n";
118 $offset += 64;
119 $segment = substr( $parts[2], $offset, 64 );
120 }
121 $encoding .= '-----' . $parts[3] . "-----\n";
122 $public_key = $encoding;
123 }
124
125 switch ( $sha ) {
126 case '256':
127 $verified = openssl_verify( $jwt_data, $jwt_signature, $public_key, OPENSSL_ALGO_SHA256 );
128 break;
129 case '384':
130 $verified = openssl_verify( $jwt_data, $jwt_signature, $public_key, OPENSSL_ALGO_SHA384 );
131 break;
132 case '512':
133 $verified = openssl_verify( $jwt_data, $jwt_signature, $public_key, OPENSSL_ALGO_SHA512 );
134 break;
135 default:
136 $verified = false;
137 break;
138 }
139
140 if ( ! $verified ) {
141 echo 'Invalid Token';
142 exit();
143 }
144
145 $jwt_payload = json_decode( base64_decode( $pieces[1] ), true ); //phpcs:ignore -- ignoring DiscouragedPHPFunctions warning as this line of code is used for decoding JWT payload part.
146 return $jwt_payload;
147
148 }
149
150 /**
151 * Processing Firebase JWT
152 *
153 * @param mixed $kid kid.
154 *
155 * @return mixed jwt cert
156 */
157 public function mo_firebase_auth_get_cert_from_kid( $kid ) {
158 $flag = $this->mo_firebase_auth_get_kid( $kid );
159 if ( 0 === $flag ) {
160 $firebaselogin = new Miniorange_Firebase_Authentication();
161 $firebaselogin->mo_firebase_auth_store_certificates();
162 $flag = $this->mo_firebase_auth_get_kid( $kid );
163 }
164 if ( 0 !== $flag ) {
165 if ( 1 === $flag ) {
166 $jwt_raw_certificate = get_option( 'mo_firebase_auth_cert1' );
167 } elseif ( 2 === $flag ) {
168 $jwt_raw_certificate = get_option( 'mo_firebase_auth_cert2' );
169 } elseif ( 3 === $flag ) {
170 $jwt_raw_certificate = get_option( 'mo_firebase_auth_cert3' );
171 }
172 } else {
173 echo 'Please provide a valid certificate. Contact your administrator.';
174 exit;
175 }
176 return $jwt_raw_certificate;
177 }
178
179 /**
180 * Function included in JWT processing
181 *
182 * @param mixed $kid kid.
183 *
184 * @return int
185 */
186 public function mo_firebase_auth_get_kid( $kid ) {
187 $flag = 0;
188 $kid_stored = get_option( 'mo_firebase_auth_kid1' );
189 if ( $kid_stored !== $kid ) {
190 $flag = 2;
191 $kid_stored = get_option( 'mo_firebase_auth_kid2' );
192 if ( $kid_stored !== $kid ) {
193 $flag = 3;
194 $kid_stored = get_option( 'mo_firebase_auth_kid3' );
195 if ( $kid_stored !== $kid ) {
196 $flag = 0;
197 }
198 }
199 } else {
200 $flag = 1;
201 }
202 return $flag;
203 }
204
205 /**
206 * Check the user and set the session or return WP error
207 *
208 * @param mixed $fb_idtoken firebase Id token.
209 *
210 * @return object WP_User/WP_Error .
211 */
212 public function mo_fb_login_user( $fb_idtoken ) {
213
214 $payload = $this->decode_jwt( $fb_idtoken );
215
216 $user = $this->get_user( $payload );
217 if ( is_wp_error( $user ) ) {
218 return $user;
219 } else {
220 $user_id = $user->ID;
221 wp_set_auth_cookie( $user_id, true );
222 wp_safe_redirect( home_url() );
223 exit;
224 }
225
226 }
227
228 /**
229 * Get the user object from WordPress
230 *
231 * @param array $jwt_payload Firebase Id token payload.
232 */
233 public function get_user( $jwt_payload ) {
234 if ( isset( $jwt_payload['email'] ) ) {
235 $email = $jwt_payload['email'];
236 $user = get_user_by( 'email', $email );
237 if ( ! $user ) {
238 $user = get_user_by( 'login', $email );
239 if ( $user ) {
240 return $user;
241 } else {
242 $user_password = wp_generate_password( 10, false );
243
244 $userdata = array(
245 'user_login' => $email,
246 'user_pass' => $user_password,
247 'user_email' => $email,
248 );
249
250 $user_id = wp_insert_user( $userdata );
251
252 if ( ! is_wp_error( $user_id ) ) {
253 // Store disting
254 // shedName in User Meta.
255 update_user_meta( $user_id, 'mo_firebase_user_dn', false );
256 }
257
258 $user = get_user_by( 'email', $email );
259 return $user;
260 }
261 } elseif ( $user ) {
262 return $user;
263 }
264 }
265 }
266 /**
267 * Function to call Firebase email password API
268 *
269 * @param string $url .
270 * @param string $headers .
271 * @param string $body .
272 */
273 public function mo_fb_post_api( $url, $headers, $body ) {
274
275 $args = array(
276 'method' => 'POST',
277 'body' => $body,
278 'timeout' => '5',
279 'redirection' => '5',
280 'httpversion' => '1.0',
281 'blocking' => true,
282 'headers' => $headers,
283
284 );
285
286 $response = wp_remote_post( $url, $args );
287
288 if ( is_wp_error( $response ) ) {
289 $error_message = $response->get_error_message();
290 echo 'Something went wrong: ' . esc_attr( $error_message );
291 exit();
292 }
293
294 return wp_remote_retrieve_body( $response );
295 }
296
297 /**
298 * Function to call Firebase email password API
299 *
300 * @param string $email .
301 * @param string $password .
302 */
303 public function mo_firebase_authenticate_call( $email, $password ) {
304
305 $api_key = get_option( 'mo_firebase_auth_api_key' );
306
307 $url = 'https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=' . $api_key;
308
309 $params = array(
310 'email' => $email,
311 'password' => $password,
312 'returnSecureToken' => true,
313 );
314
315 $body = wp_json_encode( $params );
316
317 $headers = array(
318 'Content-Type' => 'application/json',
319 'Content-Length' => strlen( $body ),
320 );
321
322 $response = $this->mo_fb_post_api( $url, $headers, $body );
323
324 return $response;
325 }
326
327 }
328
329 $mo_firebase_config_obj = new Mo_Firebase_Config();
330