mirror of
				https://github.com/beestat/app.git
				synced 2025-10-31 01:57: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 | ||||
|  */ | ||||
| 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->extra = $extra; | ||||
|     $this->extra_info = $extra_info; | ||||
|     $this->rollback = $rollback; | ||||
|     return parent::__construct($message, $code, null); | ||||
|   } | ||||
| 
 | ||||
| @ -25,6 +26,10 @@ final class exception extends \Exception { | ||||
|   } | ||||
| 
 | ||||
|   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; | ||||
| 
 | ||||
|   /** | ||||
|    * 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 | ||||
|    */ | ||||
|   private $queued_creates = []; | ||||
|   private $queued_database_actions = []; | ||||
| 
 | ||||
|   /** | ||||
|    * Save the request variables for use later on. If unset, they are defaulted | ||||
| @ -439,6 +439,7 @@ final class request { | ||||
|     $this->set_error_response( | ||||
|       $error_message, | ||||
|       $error_code, | ||||
|       true, | ||||
|       true | ||||
|     ); | ||||
| 
 | ||||
| @ -468,7 +469,8 @@ final class request { | ||||
|     $this->set_error_response( | ||||
|       $e->getMessage(), | ||||
|       $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 { | ||||
| @ -489,23 +491,26 @@ final class request { | ||||
|    * | ||||
|    * 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 | ||||
|    * occurs, rollback the current transaction. | ||||
|    * occurs, rollback the current transaction unless specified otherwise. | ||||
|    * | ||||
|    * @param string $error_message The error message. | ||||
|    * @param mixed $error_code The supplied error code. | ||||
|    * @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(); | ||||
|     $session = session::get_instance(); | ||||
| 
 | ||||
|     // I guess if this fails then things are really bad, but let's at least
 | ||||
|     // protect against additional exceptions if the database connection or
 | ||||
|     // similar fails.
 | ||||
|     try { | ||||
|       $database = database::get_instance(); | ||||
|       $database->rollback_transaction(); | ||||
|     } catch(\Exception $e) {} | ||||
|     if($rollback === true) { | ||||
|       try { | ||||
|         $database = database::get_instance(); | ||||
|         $database->rollback_transaction(); | ||||
|       } catch(\Exception $e) {} | ||||
|     } | ||||
| 
 | ||||
|     $this->response = [ | ||||
|       'success' => false, | ||||
| @ -595,8 +600,29 @@ final class request { | ||||
|       chdir($this->current_working_directory); | ||||
| 
 | ||||
|       // Run any queued creates.
 | ||||
|       foreach($this->queued_creates as $queued_create) { | ||||
|         $database->create($queued_create['resource'], $queued_create['attributes'], 'id'); | ||||
|       foreach($this->queued_database_actions as $queued_database_action) { | ||||
|         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
 | ||||
| @ -611,6 +637,7 @@ final class request { | ||||
|         $this->set_error_response( | ||||
|           $error['message'], | ||||
|           $error['type'], | ||||
|           true, | ||||
|           true | ||||
|         ); | ||||
| 
 | ||||
| @ -666,7 +693,8 @@ final class request { | ||||
|       $this->set_error_response( | ||||
|         $e->getMessage(), | ||||
|         $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 { | ||||
| @ -684,12 +712,15 @@ final class request { | ||||
|    * be used for logging things as these will not be affected by transaction | ||||
|    * rollbacks in the event of an exception. | ||||
|    * | ||||
|    * @param string $resource | ||||
|    * @param array $attributes | ||||
|    * @param string $resource The database table to act on. | ||||
|    * @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) { | ||||
|     $this->queued_creates[] = [ | ||||
|   public function queue_database_action($resource, $method, $attributes) { | ||||
|     $this->queued_database_actions[] = [ | ||||
|       'resource' => $resource, | ||||
|       'method' => $method, | ||||
|       'attributes' => $attributes | ||||
|     ]; | ||||
|   } | ||||
|  | ||||
| @ -164,7 +164,7 @@ class ecobee extends external_api { | ||||
|           [] | ||||
|         ); | ||||
|         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); | ||||
|         } | ||||
|         $ecobee_token = $ecobee_tokens[0]; | ||||
| @ -227,8 +227,7 @@ class ecobee extends external_api { | ||||
|         $this->log_mysql($curl_response, true); | ||||
|       } | ||||
|       $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); | ||||
|       throw new cora\exception('Ecobee access was revoked by user.', 10500, false, null, false); | ||||
|     } | ||||
|     else if (isset($response['status']) === true && $response['status']['code'] !== 0) { | ||||
|       // Any other error
 | ||||
| @ -240,10 +239,16 @@ class ecobee extends external_api { | ||||
|     else if (isset($response['error']) === true) { | ||||
|       // Authorization errors are a bit different
 | ||||
|       // 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') { | ||||
|         $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 { | ||||
|       return $response; | ||||
|  | ||||
| @ -97,9 +97,8 @@ class ecobee_token extends cora\crud { | ||||
|       isset($response['refresh_token']) === false | ||||
|     ) { | ||||
|       $this->delete($ecobee_token['ecobee_token_id']); | ||||
|       $this->api('user', 'log_out', ['all' => true]); | ||||
|       $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( | ||||
| @ -118,19 +117,16 @@ class ecobee_token extends cora\crud { | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|    * Delete an ecobee token. If this happens immediately log out all of this | ||||
|    * user's currently logged in sessions. | ||||
|    * Delete an ecobee 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 | ||||
|    * | ||||
|    * @return int | ||||
|    */ | ||||
|   public function delete($id) { | ||||
|     $database = cora\database::get_transactionless_instance(); | ||||
| 
 | ||||
|     // Need to delete the token before logging out or else the delete fails.
 | ||||
|     $return = $database->delete($this->resource, $id); | ||||
| 
 | ||||
|     $return = parent::delete($id); | ||||
|     $this->api('user', 'log_out'); | ||||
|     return $return; | ||||
|   } | ||||
| 
 | ||||
|  | ||||
| @ -16,7 +16,7 @@ class external_api_log extends cora\crud { | ||||
|    */ | ||||
|   public function create($attributes) { | ||||
|     $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']); | ||||
|       $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( | ||||
| @ -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 | ||||
|    * | ||||
|    * @return int | ||||
|    */ | ||||
|   public function delete($id) { | ||||
|     $database = cora\database::get_transactionless_instance(); | ||||
|     $return = $database->delete($this->resource, $id); | ||||
|     return $return; | ||||
|     return parent::delete($id); | ||||
|   } | ||||
| 
 | ||||
| } | ||||
|  | ||||
							
								
								
									
										28
									
								
								api/user.php
									
									
									
									
									
								
							
							
						
						
									
										28
									
								
								api/user.php
									
									
									
									
									
								
							| @ -131,37 +131,13 @@ class user extends cora\crud { | ||||
| 
 | ||||
|   /** | ||||
|    * 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) { | ||||
|       return; | ||||
|     } | ||||
| 
 | ||||
|     if($all === true) { | ||||
|       // 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(); | ||||
|     } | ||||
|     return $this->session->delete(); | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|  | ||||
| @ -192,11 +192,7 @@ beestat.component.header.prototype.decorate_ = function(parent) { | ||||
|         .set_callback(function() { | ||||
|           window.location.href = window.location.href.replace('app.', ''); | ||||
|         }) | ||||
|         .add_call( | ||||
|           'user', | ||||
|           'log_out', | ||||
|           {'all': false} | ||||
|         ) | ||||
|         .add_call('user', 'log_out') | ||||
|         .send(); | ||||
|     })); | ||||
| }; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user