PluginProbe
Search Atlas SEO – OTTO AI SEO Automation for WordPress / 2.6.7
Search Atlas SEO – OTTO AI SEO Automation for WordPress v2.6.7
2.6.26 2.6.25 2.6.24 2.6.23 2.6.22 2.6.21 2.6.20 2.6.19 2.6.18 2.6.17 2.6.16 2.6.15 2.6.14 2.6.13 2.6.12 2.6.11 2.6.10 2.6.9 2.6.8 2.6.7 2.6.6 2.6.5 2.6.4 2.6.3 2.5.23 All 138 releases
metasync / includes / class-metasync-auth-manager.php

class-metasync-auth-manager.php in Search Atlas SEO – OTTO AI SEO Automation for WordPress 2.6.7, at includes/class-metasync-auth-manager.php

405 lines 11.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Authentication Manager for MetaSync Plugin
4 *
5 * Provides secure, transient-based authentication for protected areas
6 * Replaces session-based authentication with WordPress-native solutions
7 *
8 * Best Practices:
9 * - Uses WordPress Transients (works with object caching, Redis, Memcached)
10 * - User Meta for persistent access
11 * - No PHP sessions (works on all hosting environments)
12 * - OOP design for reusability
13 * - Supports multiple authentication contexts
14 *
15 * @package MetaSync
16 * @subpackage MetaSync/includes
17 * @since 2.5.12
18 */
19
20 // Prevent direct access
21 if (!defined('ABSPATH')) {
22 exit;
23 }
24
25 class Metasync_Auth_Manager {
26
27 /**
28 * Authentication context identifier
29 *
30 * @var string
31 */
32 private $context;
33
34 /**
35 * Transient timeout in seconds (default: 30 minutes)
36 *
37 * @var int
38 */
39 private $transient_timeout = 1800;
40
41 /**
42 * User meta key for persistent access
43 *
44 * @var string
45 */
46 private $user_meta_key;
47
48 /**
49 * Current user ID
50 *
51 * @var int|null
52 */
53 private $user_id;
54
55 /**
56 * Constructor
57 *
58 * @param string $context Authentication context (e.g., 'debug', 'whitelabel')
59 * @param int $timeout Transient timeout in seconds (default: 1800 = 30 minutes)
60 */
61 public function __construct($context = 'default', $timeout = 1800) {
62 $this->context = sanitize_key($context);
63 $this->transient_timeout = absint($timeout);
64 $this->user_meta_key = 'metasync_' . $this->context . '_access';
65
66 // Don't call wp_get_current_user() in constructor - it might not be available yet
67 // Will be set lazily when needed via get_user_id()
68 $this->user_id = null;
69 }
70
71 /**
72 * Get current user ID (lazy loaded)
73 *
74 * @return int|null User ID or null if not available
75 */
76 private function get_user_id() {
77 if ($this->user_id === null && function_exists('wp_get_current_user')) {
78 $current_user = wp_get_current_user();
79 $this->user_id = $current_user && $current_user->ID ? $current_user->ID : 0;
80 }
81 return $this->user_id > 0 ? $this->user_id : null;
82 }
83
84 /**
85 * Check if user has access (checks both persistent and transient)
86 *
87 * @return bool True if user has access, false otherwise
88 */
89 public function has_access() {
90 $user_id = $this->get_user_id();
91 if (!$user_id) {
92 return false;
93 }
94
95 // Check persistent access (user meta)
96 if ($this->has_persistent_access()) {
97 // Refresh transient activity
98 $this->update_activity();
99 return true;
100 }
101
102 // Check temporary access (transient)
103 if ($this->has_transient_access()) {
104 // Refresh transient activity
105 $this->update_activity();
106 return true;
107 }
108
109 return false;
110 }
111
112 /**
113 * Check if user has persistent access via user meta
114 *
115 * @return bool
116 */
117 public function has_persistent_access() {
118 $user_id = $this->get_user_id();
119 if (!$user_id) {
120 return false;
121 }
122
123 $access = get_user_meta($user_id, $this->user_meta_key, true);
124 return $access === 'granted';
125 }
126
127 /**
128 * Check if user has temporary access via transient
129 *
130 * @return bool
131 */
132 public function has_transient_access() {
133 $user_id = $this->get_user_id();
134 if (!$user_id) {
135 return false;
136 }
137
138 $transient_key = $this->get_transient_key();
139 $access = get_transient($transient_key);
140 return $access === 'granted';
141 }
142
143 /**
144 * Grant persistent access (user meta)
145 *
146 * @return bool True on success, false on failure
147 */
148 public function grant_persistent_access() {
149 $user_id = $this->get_user_id();
150 if (!$user_id) {
151 return false;
152 }
153
154 $result = update_user_meta($user_id, $this->user_meta_key, 'granted');
155
156 // Also set transient for immediate access
157 $this->grant_transient_access();
158
159 return $result !== false;
160 }
161
162 /**
163 * Grant temporary access (transient)
164 *
165 * @return bool True on success, false on failure
166 */
167 public function grant_transient_access() {
168 $user_id = $this->get_user_id();
169 if (!$user_id) {
170 return false;
171 }
172
173 $transient_key = $this->get_transient_key();
174 $result = set_transient($transient_key, 'granted', $this->transient_timeout);
175
176 // Set activity timestamp
177 $this->update_activity();
178
179 return $result;
180 }
181
182 /**
183 * Revoke all access (both persistent and transient)
184 *
185 * @return bool True on success, false on failure
186 */
187 public function revoke_access() {
188 $user_id = $this->get_user_id();
189 if (!$user_id) {
190 return false;
191 }
192
193 // Delete user meta
194 delete_user_meta($user_id, $this->user_meta_key);
195
196 // Delete transients
197 delete_transient($this->get_transient_key());
198 delete_transient($this->get_activity_transient_key());
199
200 return true;
201 }
202
203 /**
204 * Revoke only persistent access (keeps transient until expiration)
205 *
206 * @return bool True on success, false on failure
207 */
208 public function revoke_persistent_access() {
209 $user_id = $this->get_user_id();
210 if (!$user_id) {
211 return false;
212 }
213
214 return delete_user_meta($user_id, $this->user_meta_key);
215 }
216
217 /**
218 * Revoke only transient access (keeps persistent if granted)
219 *
220 * @return bool True on success, false on failure
221 */
222 public function revoke_transient_access() {
223 $user_id = $this->get_user_id();
224 if (!$user_id) {
225 return false;
226 }
227
228 delete_transient($this->get_transient_key());
229 delete_transient($this->get_activity_transient_key());
230
231 return true;
232 }
233
234 /**
235 * Update last activity timestamp
236 *
237 * @return bool True on success, false on failure
238 */
239 private function update_activity() {
240 $user_id = $this->get_user_id();
241 if (!$user_id) {
242 return false;
243 }
244
245 $activity_key = $this->get_activity_transient_key();
246 return set_transient($activity_key, time(), $this->transient_timeout);
247 }
248
249 /**
250 * Get last activity timestamp
251 *
252 * @return int|false Timestamp or false if not found
253 */
254 public function get_last_activity() {
255 $user_id = $this->get_user_id();
256 if (!$user_id) {
257 return false;
258 }
259
260 $activity_key = $this->get_activity_transient_key();
261 return get_transient($activity_key);
262 }
263
264 /**
265 * Check if access has timed out due to inactivity
266 *
267 * @return bool True if timed out, false otherwise
268 */
269 public function is_timed_out() {
270 $last_activity = $this->get_last_activity();
271
272 if ($last_activity === false) {
273 return true;
274 }
275
276 $inactive_time = time() - $last_activity;
277 return $inactive_time > $this->transient_timeout;
278 }
279
280 /**
281 * Get transient key for this user and context
282 *
283 * @return string|false Returns transient key or false if no user ID available
284 */
285 private function get_transient_key() {
286 $user_id = $this->get_user_id();
287 if (!$user_id) {
288 return false;
289 }
290 return 'metasync_auth_' . $this->context . '_' . $user_id;
291 }
292
293 /**
294 * Get activity transient key for this user and context
295 *
296 * @return string|false Returns transient key or false if no user ID available
297 */
298 private function get_activity_transient_key() {
299 $user_id = $this->get_user_id();
300 if (!$user_id) {
301 return false;
302 }
303 return 'metasync_activity_' . $this->context . '_' . $user_id;
304 }
305
306 /**
307 * Get authentication status information
308 *
309 * @return array Status information
310 */
311 public function get_status() {
312 $user_id = $this->get_user_id();
313 if (!$user_id) {
314 return array(
315 'authenticated' => false,
316 'user_id' => null,
317 'context' => $this->context,
318 'error' => 'No user logged in'
319 );
320 }
321
322 return array(
323 'authenticated' => $this->has_access(),
324 'user_id' => $user_id,
325 'context' => $this->context,
326 'persistent_access' => $this->has_persistent_access(),
327 'transient_access' => $this->has_transient_access(),
328 'last_activity' => $this->get_last_activity(),
329 'is_timed_out' => $this->is_timed_out(),
330 'transient_timeout' => $this->transient_timeout,
331 'user_meta_key' => $this->user_meta_key
332 );
333 }
334
335 /**
336 * Verify password and grant access
337 *
338 * @param string $password Password to verify
339 * @param string|array $valid_passwords Valid password(s) to check against
340 * @param bool $persistent Whether to grant persistent access
341 * @return bool True if password is valid and access granted, false otherwise
342 */
343 public function verify_and_grant($password, $valid_passwords, $persistent = false) {
344 if (!is_array($valid_passwords)) {
345 $valid_passwords = array($valid_passwords);
346 }
347
348 // Remove empty passwords
349 $valid_passwords = array_filter($valid_passwords);
350
351 if (empty($valid_passwords)) {
352 return false;
353 }
354
355 // Check if password matches any valid password
356 $password_valid = in_array($password, $valid_passwords, true);
357
358 if ($password_valid) {
359 if ($persistent) {
360 return $this->grant_persistent_access();
361 } else {
362 return $this->grant_transient_access();
363 }
364 }
365
366 return false;
367 }
368
369 /**
370 * Static helper: Grant persistent access to a user
371 *
372 * @param int $user_id User ID
373 * @param string $context Authentication context
374 * @return bool True on success, false on failure
375 */
376 public static function grant_user_access($user_id, $context = 'default') {
377 $user_meta_key = 'metasync_' . sanitize_key($context) . '_access';
378 return update_user_meta($user_id, $user_meta_key, 'granted') !== false;
379 }
380
381 /**
382 * Static helper: Revoke persistent access from a user
383 *
384 * @param int $user_id User ID
385 * @param string $context Authentication context
386 * @return bool True on success, false on failure
387 */
388 public static function revoke_user_access($user_id, $context = 'default') {
389 $user_meta_key = 'metasync_' . sanitize_key($context) . '_access';
390 return delete_user_meta($user_id, $user_meta_key);
391 }
392
393 /**
394 * Static helper: Check if user has access
395 *
396 * @param int $user_id User ID
397 * @param string $context Authentication context
398 * @return bool True if user has access, false otherwise
399 */
400 public static function user_has_access($user_id, $context = 'default') {
401 $auth = new self($context);
402 return $auth->has_access();
403 }
404 }
405