Add button to delete an account

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
This commit is contained in:
Morris Jobke 2020-05-29 22:52:01 +02:00 committed by Joas Schilling
parent 387e775896
commit 2071501469
No known key found for this signature in database
GPG key ID: 7076EA9751AACDDA
4 changed files with 193 additions and 0 deletions

View file

@ -461,5 +461,13 @@ return [
'apiVersion' => 'v1',
],
],
[
'name' => 'HostedSignalingServer#deleteAccount',
'url' => '/api/{apiVersion}/hostedsignalingserver/delete',
'verb' => 'DELETE',
'requirements' => [
'apiVersion' => 'v1',
],
],
],
];

View file

@ -25,6 +25,7 @@ declare(strict_types=1);
namespace OCA\Talk\Controller;
use OCA\Talk\DataObjects\AccountId;
use OCA\Talk\DataObjects\RegisterAccountData;
use OCA\Talk\Exceptions\HostedSignalingServerAPIException;
use OCA\Talk\Exceptions\HostedSignalingServerInputException;
@ -105,4 +106,33 @@ class HostedSignalingServerController extends OCSController {
return new DataResponse($accountInfo);
}
public function deleteAccount(): DataResponse {
$accountId = $this->config->getAppValue('spreed', 'hosted-signaling-server-account-id');
if ($accountId === null) {
return new DataResponse(['message' => $this->l10n->t('No account availble to delete.')], Http::STATUS_BAD_REQUEST);
}
try {
$this->hostedSignalingServerService->deleteAccount(new AccountId($accountId));
$this->config->deleteAppValue('spreed', 'hosted-signaling-server-account');
$this->config->deleteAppValue('spreed', 'hosted-signaling-server-account-id');
// remove signaling servers if account is not active anymore
$this->config->setAppValue('spreed', 'signaling_mode', 'internal');
$this->config->setAppValue('spreed', 'signaling_servers', json_encode([
'servers' => [],
'secret' => '',
]));
$this->logger->info('Deleted hosted signaling server account with ID ' . $accountId, ['app' => 'spreed']);
} catch (HostedSignalingServerAPIException $e) { // API or connection issues
return new DataResponse(['message' => $e->getMessage()], Http::STATUS_INTERNAL_SERVER_ERROR);
}
return new DataResponse([], Http::STATUS_NO_CONTENT);
}
}

View file

@ -410,4 +410,124 @@ class HostedSignalingServerService {
return $data;
}
/**
* @throws HostedSignalingServerAPIException
*/
public function deleteAccount(AccountId $accountId) {
try {
$nonce = $this->secureRandom->generate(32);
$this->config->setAppValue('spreed', 'hosted-signaling-server-nonce', $nonce);
$client = $this->clientService->newClient();
$response = $client->delete($this->apiServerUrl . '/v1/account/' . $accountId->get(), [
'headers' => [
'X-Account-Service-Nonce' => $nonce,
],
'timeout' => 10,
]);
// this is needed here because the delete happens in a concurrent request
// and thus the cached value in the config object would trigger an UPDATE
// instead of an INSERT if there is another request to the API server
$this->config->deleteAppValue('spreed', 'hosted-signaling-server-nonce');
} catch (ClientException $e) {
$response = $e->getResponse();
if ($response === null) {
$this->logger->logException($e, [
'app' => 'spreed',
'message' => 'Deleting the hosted signaling server account failed',
]);
$message = $this->l10n->t('Deleting the hosted signaling server account failed. Please check back later.');
throw new HostedSignalingServerAPIException($message);
}
$status = $response->getStatusCode();
switch ($status) {
case Http::STATUS_UNAUTHORIZED:
$body = $response->getBody()->getContents();
$this->logger->error('Deleting the hosted signaling server account failed: unauthorized - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
$message = $this->l10n->t('There is a problem with the authentication of this request. Maybe it is not reachable from the outside to verify it\'s URL.');
throw new HostedSignalingServerAPIException($message);
case Http::STATUS_BAD_REQUEST:
$body = $response->getBody()->getContents();
if ($body) {
$parsedBody = json_decode($body, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$this->logger->error('Deleting the hosted signaling server account failed: cannot parse JSON response - JSON error: '. json_last_error() . ' ' . json_last_error_msg() . ' HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
$message = $this->l10n->t('Something unexpected happened.');
throw new HostedSignalingServerAPIException($message);
}
if ($parsedBody['reason']) {
switch ($parsedBody['reason']) {
case 'missing_account_id':
$log = 'The account ID is missing.';
break;
default:
$body = $response->getBody()->getContents();
$this->logger->error('Deleting the hosted signaling server account failed: something else happened - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
$message = $this->l10n->t('Failed to delete the account because the trial server behaved wrongly. Please check back later.');
throw new HostedSignalingServerAPIException($message);
}
$this->logger->error('Deleting the hosted signaling server account failed: bad request - reason: ' . $parsedBody['reason'] . ' ' . $log);
$message = $this->l10n->t('There is a problem with deleting the account. Please check your logs for further information.');
throw new HostedSignalingServerAPIException($message);
}
}
$message = $this->l10n->t('Something unexpected happened.');
throw new HostedSignalingServerAPIException($message);
case Http::STATUS_TOO_MANY_REQUESTS:
$body = $response->getBody()->getContents();
$this->logger->error('Deleting the hosted signaling server account failed: too many requests - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
$message = $this->l10n->t('Too many requests are send from your servers address. Please try again later.');
throw new HostedSignalingServerAPIException($message);
case Http::STATUS_NOT_FOUND:
$body = $response->getBody()->getContents();
$this->logger->error('Deleting the hosted signaling server account failed: account not found - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
$message = $this->l10n->t('There is no such account registered.');
throw new HostedSignalingServerAPIException($message);
case Http::STATUS_INTERNAL_SERVER_ERROR:
$body = $response->getBody()->getContents();
$this->logger->error('Deleting the hosted signaling server account failed: internal server error - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
$message = $this->l10n->t('Something unexpected happened. Please try again later.');
throw new HostedSignalingServerAPIException($message);
default:
$body = $response->getBody()->getContents();
$this->logger->error('Deleting the hosted signaling server account failed: something else happened - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
$message = $this->l10n->t('Failed to delete the account because the trial server behaved wrongly. Please check back later.');
throw new HostedSignalingServerAPIException($message);
}
} catch (\Exception $e) {
$this->logger->logException($e, [
'app' => 'spreed',
'message' => 'Deleting the hosted signaling server account failed',
]);
$message = $this->l10n->t('Failed to delete the account because the trial server is unreachable. Please check back later.');
throw new HostedSignalingServerAPIException($message);
}
$status = $response->getStatusCode();
if ($status !== Http::STATUS_NO_CONTENT) {
$body = $response->getBody();
$this->logger->error('Deleting the hosted signaling server account failed: something else happened - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
$message = $this->l10n->t('Something unexpected happened.');
throw new HostedSignalingServerAPIException($message);
}
}
}

View file

@ -116,6 +116,15 @@
<td>{{ n('spreed', '%n user', '%n users', trailAccount.limits.users) }}</td>
</tr>
</table>
<p v-if="requestError !== ''"
class="warning">
{{ requestError }}
</p>
<button class="button delete"
:disabled="loading"
@click="deleteAccount">
{{ t('spreed', 'Delete the signaling server account') }}
</button>
</div>
</div>
</template>
@ -216,6 +225,21 @@ export default {
this.loading = false
}
},
async deleteAccount() {
this.requestError = ''
this.loading = true
try {
await axios.delete(generateOcsUrl('apps/spreed/api/v1/hostedsignalingserver', 2) + 'delete')
this.trailAccount = []
} catch (err) {
this.deleteError = err?.response?.data?.ocs?.data?.message || t('spreed', 'The account could not be deleted. Please try again later.')
} finally {
this.loading = false
}
},
},
}
</script>
@ -237,5 +261,16 @@ tr:last-child td {
tr :first-child {
opacity: .5;
}
.delete {
background: var(--color-main-background);
border-color: var(--color-error);
color: var(--color-error);
}
.delete:hover,
.delete:active {
background: var(--color-error);
border-color: var(--color-error) !important;
color: var(--color-main-background);
}
</style>