mirror of
https://github.com/beestat/app.git
synced 2025-07-08 18:54:05 -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.
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
26
api/user.php
26
api/user.php
@ -131,38 +131,14 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
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