mirror of
				https://github.com/beestat/app.git
				synced 2025-10-31 10:07:01 -04:00 
			
		
		
		
	Fixed ecobee tokens not always deleting when they are revoked.
This commit is contained in:
		
							parent
							
								
									01656e2cff
								
							
						
					
					
						commit
						159670e08c
					
				| @ -14,9 +14,10 @@ namespace cora; | |||||||
|  * @author Jon Ziebell |  * @author Jon Ziebell | ||||||
|  */ |  */ | ||||||
| final class exception extends \Exception { | final class exception extends \Exception { | ||||||
|   public function __construct($message, $code, $reportable = true, $extra = null) { |   public function __construct($message, $code, $reportable = true, $extra_info = null, $rollback = true) { | ||||||
|     $this->reportable = $reportable; |     $this->reportable = $reportable; | ||||||
|     $this->extra = $extra; |     $this->extra_info = $extra_info; | ||||||
|  |     $this->rollback = $rollback; | ||||||
|     return parent::__construct($message, $code, null); |     return parent::__construct($message, $code, null); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -25,6 +26,10 @@ final class exception extends \Exception { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   public function getExtraInfo() { |   public function getExtraInfo() { | ||||||
|     return $this->extra; |     return $this->extra_info; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   public function getRollback() { | ||||||
|  |     return $this->rollback; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -100,11 +100,11 @@ final class request { | |||||||
|   private $current_working_directory; |   private $current_working_directory; | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * A list of create calls queued up to run at the end of the request. |    * A list of database calls to make at the very end of the script. | ||||||
|    * |    * | ||||||
|    * @var array |    * @var array | ||||||
|    */ |    */ | ||||||
|   private $queued_creates = []; |   private $queued_database_actions = []; | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * Save the request variables for use later on. If unset, they are defaulted |    * Save the request variables for use later on. If unset, they are defaulted | ||||||
| @ -439,6 +439,7 @@ final class request { | |||||||
|     $this->set_error_response( |     $this->set_error_response( | ||||||
|       $error_message, |       $error_message, | ||||||
|       $error_code, |       $error_code, | ||||||
|  |       true, | ||||||
|       true |       true | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
| @ -468,7 +469,8 @@ final class request { | |||||||
|     $this->set_error_response( |     $this->set_error_response( | ||||||
|       $e->getMessage(), |       $e->getMessage(), | ||||||
|       $e->getCode(), |       $e->getCode(), | ||||||
|       (method_exists($e, 'getReportable') === true ? $e->getReportable() : true) |       (method_exists($e, 'getReportable') === true ? $e->getReportable() : true), | ||||||
|  |       (method_exists($e, 'getRollback') === true ? $e->getRollback() : true) | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
|     try { |     try { | ||||||
| @ -489,23 +491,26 @@ final class request { | |||||||
|    * |    * | ||||||
|    * There are a few places that call this function to set an error response, |    * There are a few places that call this function to set an error response, | ||||||
|    * so this can't just be done in the exception handler alone. If an error |    * so this can't just be done in the exception handler alone. If an error | ||||||
|    * occurs, rollback the current transaction. |    * occurs, rollback the current transaction unless specified otherwise. | ||||||
|    * |    * | ||||||
|    * @param string $error_message The error message. |    * @param string $error_message The error message. | ||||||
|    * @param mixed $error_code The supplied error code. |    * @param mixed $error_code The supplied error code. | ||||||
|    * @param array $reportable Whether or not the error is reportable. |    * @param array $reportable Whether or not the error is reportable. | ||||||
|  |    * @param array $rollback Whether or not the error should cause a rollback. | ||||||
|    */ |    */ | ||||||
|   public function set_error_response($error_message, $error_code, $reportable) { |   public function set_error_response($error_message, $error_code, $reportable, $rollback) { | ||||||
|     $setting = setting::get_instance(); |     $setting = setting::get_instance(); | ||||||
|     $session = session::get_instance(); |     $session = session::get_instance(); | ||||||
| 
 | 
 | ||||||
|     // I guess if this fails then things are really bad, but let's at least
 |     // I guess if this fails then things are really bad, but let's at least
 | ||||||
|     // protect against additional exceptions if the database connection or
 |     // protect against additional exceptions if the database connection or
 | ||||||
|     // similar fails.
 |     // similar fails.
 | ||||||
|     try { |     if($rollback === true) { | ||||||
|       $database = database::get_instance(); |       try { | ||||||
|       $database->rollback_transaction(); |         $database = database::get_instance(); | ||||||
|     } catch(\Exception $e) {} |         $database->rollback_transaction(); | ||||||
|  |       } catch(\Exception $e) {} | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     $this->response = [ |     $this->response = [ | ||||||
|       'success' => false, |       'success' => false, | ||||||
| @ -595,8 +600,29 @@ final class request { | |||||||
|       chdir($this->current_working_directory); |       chdir($this->current_working_directory); | ||||||
| 
 | 
 | ||||||
|       // Run any queued creates.
 |       // Run any queued creates.
 | ||||||
|       foreach($this->queued_creates as $queued_create) { |       foreach($this->queued_database_actions as $queued_database_action) { | ||||||
|         $database->create($queued_create['resource'], $queued_create['attributes'], 'id'); |         switch($queued_database_action['method']) { | ||||||
|  |           case 'create': | ||||||
|  |             $database->create( | ||||||
|  |               $queued_database_action['resource'], | ||||||
|  |               $queued_database_action['attributes'], | ||||||
|  |               'id' | ||||||
|  |             ); | ||||||
|  |           break; | ||||||
|  |           case 'update': | ||||||
|  |             $database->update( | ||||||
|  |               $queued_database_action['resource'], | ||||||
|  |               $queued_database_action['attributes'], | ||||||
|  |               'id' | ||||||
|  |             ); | ||||||
|  |           break; | ||||||
|  |           case 'delete': | ||||||
|  |             $database->delete( | ||||||
|  |               $queued_database_action['resource'], | ||||||
|  |               $queued_database_action['attributes'] | ||||||
|  |             ); | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
|       // If I didn't catch an error/exception with my handlers, look here...this
 |       // If I didn't catch an error/exception with my handlers, look here...this
 | ||||||
| @ -611,6 +637,7 @@ final class request { | |||||||
|         $this->set_error_response( |         $this->set_error_response( | ||||||
|           $error['message'], |           $error['message'], | ||||||
|           $error['type'], |           $error['type'], | ||||||
|  |           true, | ||||||
|           true |           true | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
| @ -666,7 +693,8 @@ final class request { | |||||||
|       $this->set_error_response( |       $this->set_error_response( | ||||||
|         $e->getMessage(), |         $e->getMessage(), | ||||||
|         $e->getCode(), |         $e->getCode(), | ||||||
|         (method_exists($e, 'getReportable') === true ? $e->getReportable() : true) |         (method_exists($e, 'getReportable') === true ? $e->getReportable() : true), | ||||||
|  |         (method_exists($e, 'getRollback') === true ? $e->getRollback() : true) | ||||||
|       ); |       ); | ||||||
| 
 | 
 | ||||||
|       try { |       try { | ||||||
| @ -684,12 +712,15 @@ final class request { | |||||||
|    * be used for logging things as these will not be affected by transaction |    * be used for logging things as these will not be affected by transaction | ||||||
|    * rollbacks in the event of an exception. |    * rollbacks in the event of an exception. | ||||||
|    * |    * | ||||||
|    * @param string $resource |    * @param string $resource The database table to act on. | ||||||
|    * @param array $attributes |    * @param string $method create|update|delete | ||||||
|  |    * @param array $attributes The attributes of the create or update. If | ||||||
|  |    * delete just the ID to delete. | ||||||
|    */ |    */ | ||||||
|   public function queue_create($resource, $attributes) { |   public function queue_database_action($resource, $method, $attributes) { | ||||||
|     $this->queued_creates[] = [ |     $this->queued_database_actions[] = [ | ||||||
|       'resource' => $resource, |       'resource' => $resource, | ||||||
|  |       'method' => $method, | ||||||
|       'attributes' => $attributes |       'attributes' => $attributes | ||||||
|     ]; |     ]; | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -164,7 +164,7 @@ class ecobee extends external_api { | |||||||
|           [] |           [] | ||||||
|         ); |         ); | ||||||
|         if(count($ecobee_tokens) !== 1) { |         if(count($ecobee_tokens) !== 1) { | ||||||
|           $this->api('user', 'log_out', ['all' => true]); |           $this->api('user', 'log_out'); | ||||||
|           throw new cora\exception('No ecobee access for this user.', 10501, false); |           throw new cora\exception('No ecobee access for this user.', 10501, false); | ||||||
|         } |         } | ||||||
|         $ecobee_token = $ecobee_tokens[0]; |         $ecobee_token = $ecobee_tokens[0]; | ||||||
| @ -227,8 +227,7 @@ class ecobee extends external_api { | |||||||
|         $this->log_mysql($curl_response, true); |         $this->log_mysql($curl_response, true); | ||||||
|       } |       } | ||||||
|       $this->api('ecobee_token', 'delete', $ecobee_token['ecobee_token_id']); |       $this->api('ecobee_token', 'delete', $ecobee_token['ecobee_token_id']); | ||||||
|       $this->api('user', 'log_out', ['all' => true]); |       throw new cora\exception('Ecobee access was revoked by user.', 10500, false, null, false); | ||||||
|       throw new cora\exception('Ecobee access was revoked by user.', 10500, false); |  | ||||||
|     } |     } | ||||||
|     else if (isset($response['status']) === true && $response['status']['code'] !== 0) { |     else if (isset($response['status']) === true && $response['status']['code'] !== 0) { | ||||||
|       // Any other error
 |       // Any other error
 | ||||||
| @ -240,10 +239,16 @@ class ecobee extends external_api { | |||||||
|     else if (isset($response['error']) === true) { |     else if (isset($response['error']) === true) { | ||||||
|       // Authorization errors are a bit different
 |       // Authorization errors are a bit different
 | ||||||
|       // https://www.ecobee.com/home/developer/api/documentation/v1/auth/auth-req-resp.shtml
 |       // https://www.ecobee.com/home/developer/api/documentation/v1/auth/auth-req-resp.shtml
 | ||||||
|  | 
 | ||||||
|  |       if($response['error'] === 'invalid_grant') { | ||||||
|  |         $ecobee_token = $this->api('ecobee_token', 'read')[0]; | ||||||
|  |         $this->api('ecobee_token', 'delete', $ecobee_token['ecobee_token_id']); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|       if($this::$log_mysql !== 'all') { |       if($this::$log_mysql !== 'all') { | ||||||
|         $this->log_mysql($curl_response, true); |         $this->log_mysql($curl_response, true); | ||||||
|       } |       } | ||||||
|       throw new cora\exception(isset($response['error_description']) === true ? $response['error_description'] : $response['error'], 10505); |       throw new cora\exception(isset($response['error_description']) === true ? $response['error_description'] : $response['error'], 10505, true, null, false); | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|       return $response; |       return $response; | ||||||
|  | |||||||
| @ -97,9 +97,8 @@ class ecobee_token extends cora\crud { | |||||||
|       isset($response['refresh_token']) === false |       isset($response['refresh_token']) === false | ||||||
|     ) { |     ) { | ||||||
|       $this->delete($ecobee_token['ecobee_token_id']); |       $this->delete($ecobee_token['ecobee_token_id']); | ||||||
|       $this->api('user', 'log_out', ['all' => true]); |  | ||||||
|       $database->release_lock($lock_name); |       $database->release_lock($lock_name); | ||||||
|       throw new cora\exception('Could not refresh ecobee token; ecobee returned no token.', 10002); |       throw new cora\exception('Could not refresh ecobee token; ecobee returned no token.', 10002, true, null, false); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     $ecobee_token = $database->update( |     $ecobee_token = $database->update( | ||||||
| @ -118,19 +117,16 @@ class ecobee_token extends cora\crud { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * Delete an ecobee token. If this happens immediately log out all of this |    * Delete an ecobee token and log the user out. Make sure to delete the | ||||||
|    * user's currently logged in sessions. |    * token prior to logging out so the right permissions are present. | ||||||
|    * |    * | ||||||
|    * @param int $id |    * @param int $id | ||||||
|    * |    * | ||||||
|    * @return int |    * @return int | ||||||
|    */ |    */ | ||||||
|   public function delete($id) { |   public function delete($id) { | ||||||
|     $database = cora\database::get_transactionless_instance(); |     $return = parent::delete($id); | ||||||
| 
 |     $this->api('user', 'log_out'); | ||||||
|     // Need to delete the token before logging out or else the delete fails.
 |  | ||||||
|     $return = $database->delete($this->resource, $id); |  | ||||||
| 
 |  | ||||||
|     return $return; |     return $return; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ class external_api_log extends cora\crud { | |||||||
|    */ |    */ | ||||||
|   public function create($attributes) { |   public function create($attributes) { | ||||||
|     $attributes['user_id'] = $this->session->get_user_id(); |     $attributes['user_id'] = $this->session->get_user_id(); | ||||||
|     $this->request->queue_create($this->resource, $attributes); |     $this->request->queue_database_action($this->resource, 'create', $attributes); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -105,7 +105,7 @@ class patreon_token extends cora\crud { | |||||||
|     ) { |     ) { | ||||||
|       $this->delete($patreon_token['patreon_token_id']); |       $this->delete($patreon_token['patreon_token_id']); | ||||||
|       $database->release_lock($lock_name); |       $database->release_lock($lock_name); | ||||||
|       throw new cora\exception('Could not refresh Patreon token; Patreon returned no token.', 10102); |       throw new cora\exception('Could not refresh Patreon token; Patreon returned no token.', 10102, true, null, false); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     $database->update( |     $database->update( | ||||||
| @ -122,16 +122,15 @@ class patreon_token extends cora\crud { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * Delete an patreon token. |    * Delete a Patreon token and log the user out. Make sure to delete the | ||||||
|  |    * token prior to logging out so the right permissions are present. | ||||||
|    * |    * | ||||||
|    * @param int $id |    * @param int $id | ||||||
|    * |    * | ||||||
|    * @return int |    * @return int | ||||||
|    */ |    */ | ||||||
|   public function delete($id) { |   public function delete($id) { | ||||||
|     $database = cora\database::get_transactionless_instance(); |     return parent::delete($id); | ||||||
|     $return = $database->delete($this->resource, $id); |  | ||||||
|     return $return; |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										28
									
								
								api/user.php
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								api/user.php
									
									
									
									
									
								
							| @ -131,37 +131,13 @@ class user extends cora\crud { | |||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|    * Logs out the currently logged in user. |    * Logs out the currently logged in user. | ||||||
|    * |  | ||||||
|    * @return bool True if it was successfully invalidated. Could return false |  | ||||||
|    * for a non-existant session key or if it was already logged out. In the |  | ||||||
|    * case of multiple sessions, return true if all open sessions were |  | ||||||
|    * successfully deleted, false if not. |  | ||||||
|    */ |    */ | ||||||
|   public function log_out($all) { |   public function log_out() { | ||||||
|     if($this->setting->is_demo() === true) { |     if($this->setting->is_demo() === true) { | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if($all === true) { |     return $this->session->delete(); | ||||||
|       // Sometimes I need to log out and then throw an exception. Using the
 |  | ||||||
|       // transactionless instance makes sure that actually works.
 |  | ||||||
|       $database = cora\database::get_transactionless_instance(); |  | ||||||
|       $sessions = $database->read( |  | ||||||
|         'cora\session', |  | ||||||
|         [ |  | ||||||
|           'user_id' => $this->session->get_user_id(), |  | ||||||
|           'api_user_id' => null |  | ||||||
|         ] |  | ||||||
|       ); |  | ||||||
|       $success = true; |  | ||||||
|       foreach($sessions as $session) { |  | ||||||
|         $success &= $database->delete('cora\session', $session['session_id']); |  | ||||||
|       } |  | ||||||
|       return $success; |  | ||||||
|     } |  | ||||||
|     else { |  | ||||||
|       return $this->session->delete(); |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   /** |   /** | ||||||
|  | |||||||
| @ -192,11 +192,7 @@ beestat.component.header.prototype.decorate_ = function(parent) { | |||||||
|         .set_callback(function() { |         .set_callback(function() { | ||||||
|           window.location.href = window.location.href.replace('app.', ''); |           window.location.href = window.location.href.replace('app.', ''); | ||||||
|         }) |         }) | ||||||
|         .add_call( |         .add_call('user', 'log_out') | ||||||
|           'user', |  | ||||||
|           'log_out', |  | ||||||
|           {'all': false} |  | ||||||
|         ) |  | ||||||
|         .send(); |         .send(); | ||||||
|     })); |     })); | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user