mirror of
https://github.com/beestat/app.git
synced 2025-07-09 03:04:07 -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.
|
||||||
|
if($rollback === true) {
|
||||||
try {
|
try {
|
||||||
$database = database::get_instance();
|
$database = database::get_instance();
|
||||||
$database->rollback_transaction();
|
$database->rollback_transaction();
|
||||||
} catch(\Exception $e) {}
|
} 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
26
api/user.php
26
api/user.php
@ -131,38 +131,14 @@ 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) {
|
|
||||||
// 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();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a setting on a user. This utilizes a lock because all settings are
|
* Set a setting on a user. This utilizes a lock because all settings are
|
||||||
|
@ -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