Browse Source

Fetch account information right after registration

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
pull/3620/head
Morris Jobke 6 years ago
committed by Joas Schilling
parent
commit
8d41e17ebd
No known key found for this signature in database GPG Key ID: 7076EA9751AACDDA
  1. 168
      lib/Controller/HostedSignalingServerController.php
  2. 3
      lib/Settings/Admin/AdminSettings.php
  3. 73
      src/components/AdminSettings/HostedSignalingServer.vue

168
lib/Controller/HostedSignalingServerController.php

@ -83,11 +83,11 @@ class HostedSignalingServerController extends OCSController {
public function requestTrial(string $url, string $name, string $email, string $language, string $country): DataResponse {
$client = $this->clientService->newClient();
$apiServer = $this->config->getSystemValue('talk_hardcoded_hpb_service', 'https://api.spreed.cloud');
try {
$nonce = $this->secureRandom->generate(32);
$this->config->setAppValue('spreed', 'hosted-signaling-server-nonce', $nonce);
$apiServer = $this->config->getSystemValue('talk_hardcoded_hpb_service', 'https://api.spreed.cloud');
$response = $client->post($apiServer . '/v1/account', [
'json' => [
'url' => $url,
@ -239,9 +239,6 @@ class HostedSignalingServerController extends OCSController {
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
// will contain the URL that can be used to query information on the account
$statusUrl = $response->getHeader('Location');
$body = $response->getBody();
$data = json_decode($body, true);
@ -260,6 +257,167 @@ class HostedSignalingServerController extends OCSController {
}
$this->config->setAppValue('spreed', 'hosted-signaling-server-account-id', $data['account_id']);
return new DataResponse([]);
$data = [
'account_id' => $this->config->getAppValue('spreed', 'hosted-signaling-server-account-id')
];
// account is now properly requested
// fetch account details
try {
$nonce = $this->secureRandom->generate(32);
$this->config->setAppValue('spreed', 'hosted-signaling-server-nonce', $nonce);
$response = $client->get($apiServer . '/v1/account/' . $data['account_id'], [
'headers' => [
'X-Account-Service-Nonce' => $nonce,
],
'timeout' => 10,
]);
} catch(ClientException $e) {
$response = $e->getResponse();
if ($response === null) {
$this->logger->logException($e, [
'app' => 'spreed',
'message' => 'Trial requested but failed to get account information',
]);
return new DataResponse([
'message' => $this->l10n->t('Trial requested but failed to get account information. Please check back later.')
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$status = $response->getStatusCode();
switch ($status) {
case Http::STATUS_UNAUTHORIZED:
// TODO log it
return new DataResponse([
'message' => $this->l10n->t('There is a problem with the authentication of this request. Maybe the account was deleted.') // TODO deleted?
], Http::STATUS_INTERNAL_SERVER_ERROR);
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('Getting the account information failed: cannot parse JSON response - JSON error: '. json_last_error() . ' ' . json_last_error_msg() . ' HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
return new DataResponse([
'message' => $this->l10n->t('Something unexpected happened.')
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
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('Getting the account information failed: something else happened - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
return new DataResponse([
'message' => $this->l10n->t('Failed to fetch account information because the trial server behaved wrongly. Please check back later.')
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$this->logger->error('Getting the account information failed: bad request - reason: ' . $parsedBody['reason'] . ' ' . $log);
return new DataResponse([
'message' => $this->l10n->t('There is a problem with fetching the account information. Please check your logs for further information.')
], Http::STATUS_BAD_REQUEST);
}
}
return new DataResponse([
'message' => $this->l10n->t('Something unexpected happened.')
], Http::STATUS_BAD_REQUEST);
case Http::STATUS_TOO_MANY_REQUESTS:
$body = $response->getBody()->getContents();
$this->logger->error('Getting the account information failed: too many requests - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
return new DataResponse([
'message' => $this->l10n->t('Too many requests are send from your servers address. Please try again later.')
], Http::STATUS_TOO_MANY_REQUESTS);
case Http::STATUS_NOT_FOUND:
$body = $response->getBody()->getContents();
$this->logger->error('Getting the account information failed: account not found - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
return new DataResponse([
'message' => $this->l10n->t('There is no such account registered.')
], Http::STATUS_CONFLICT);
case Http::STATUS_INTERNAL_SERVER_ERROR:
$body = $response->getBody()->getContents();
$this->logger->error('Getting the account information failed: internal server error - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
return new DataResponse([
'message' => $this->l10n->t('Something unexpected happened. Please try again later.')
], Http::STATUS_INTERNAL_SERVER_ERROR);
default:
$body = $response->getBody()->getContents();
$this->logger->error('Getting the account information failed: something else happened - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
return new DataResponse([
'message' => $this->l10n->t('Failed to fetch account information because the trial server behaved wrongly. Please check back later.')
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
} catch (\Exception $e) {
$this->logger->logException($e, [
'app' => 'spreed',
'message' => 'Failed to request hosted signaling server trial',
]);
return new DataResponse([
'message' => $this->l10n->t('Failed to fetch account information because the trial server is unreachable. Please check back later.')
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$status = $response->getStatusCode();
if ($status !== Http::STATUS_OK) {
$body = $response->getBody();
$this->logger->error('Getting the account information failed: something else happened - HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
return new DataResponse([
'message' => $this->l10n->t('Something unexpected happened.')
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$body = $response->getBody();
$data = json_decode($body, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$this->logger->error('Getting the account information failed: cannot parse JSON response - JSON error: '. json_last_error() . ' ' . json_last_error_msg() . ' HTTP status: ' . $status . ' Response body: ' . $body, ['app' => 'spreed']);
return new DataResponse([
'message' => $this->l10n->t('Something unexpected happened.')
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
return $this->sanitizeAndCacheAccountData($data);
}
protected function sanitizeAndCacheAccountData(array $data): DataResponse {
if (!isset($data['status'])
|| !isset($data['created'])
|| ($data['status'] === 'active' && (
!isset($data['signaling'])
|| !isset($data['signaling']['url'])
|| !isset($data['signaling']['secret'])
)
)
|| !isset($data['owner'])
|| !isset($data['owner']['url'])
|| !isset($data['owner']['name'])
|| !isset($data['owner']['email'])
|| !isset($data['owner']['language'])
|| !isset($data['owner']['country'])
|| ($data['status'] === 'active' && (
!isset($data['limits'])
|| !isset($data['limits']['users'])
)
)
|| (in_array($data['status'], ['error', 'blocked']) && !isset($data['reason']))
|| !in_array($data['status'], ['error', 'blocked', 'pending', 'active', 'expired'])
) {
$this->logger->error('Getting the account information failed: response is missing mandatory field - data: ' . json_encode($data), ['app' => 'spreed']);
return new DataResponse([
'message' => $this->l10n->t('Something unexpected happened.')
], Http::STATUS_INTERNAL_SERVER_ERROR);
}
$this->config->setAppValue('spreed', 'hosted-signaling-server-account', json_encode($data));
return new DataResponse($data);
}
}

3
lib/Settings/Admin/AdminSettings.php

@ -129,6 +129,9 @@ class AdminSettings implements ISettings {
'language' => $this->serverConfig->getUserValue($this->currentUser->getUID(), 'core', 'lang', 'en_US'),
'country' => $this->serverConfig->getUserValue($this->currentUser->getUID(), 'core', 'locale', 'en_US'),
]);
$this->initialStateService->provideInitialState('talk', 'hosted_signaling_server_trial_data',
json_decode($this->serverConfig->getAppValue('spreed', 'hosted-signaling-server-account', "[]"), true) ?? []
);
}
/**

73
src/components/AdminSettings/HostedSignalingServer.vue

@ -30,7 +30,7 @@
{{ t('spreed', 'Our partner Struktur AG provides a service where a hosted signaling server can be requested. For this you only need to fill out the form below and your Nextcloud will request it. Once the server is set up for you the credentials will be filled automatically.') }}
</p>
<div>
<div v-if="!trailAccount.status">
<h4>{{ t('spreed', 'URL of this Nextcloud instance') }}</h4>
<input
v-model="hostedHPBNextcloudUrl"
@ -81,8 +81,32 @@
class="warning">
{{ requestError }}
</p>
<p class="settings-hint additional-top-margin" v-html="disclaimerHint" />
</div>
<div v-else>
<p class="settings-hint additional-top-margin">
{{ t('spreed', 'You can see the current status of your hosted signaling server in the following table.') }}
</p>
<table>
<tr>
<td>{{ t('spreed', 'Status') }}</td>
<td>{{ translatedStatus }}</td>
</tr>
<tr>
<td>{{ t('spreed', 'Created at') }}</td>
<td>{{ createdDate }}</td>
</tr>
<tr>
<td>{{ t('spreed', 'Expires at') }}</td>
<td>{{ expiryDate }}</td>
</tr>
<tr v-if="trailAccount.limits">
<td>{{ t('spreed', 'Limits') }}</td>
<td>{{ n('spreed', '%n user', '%n users', trailAccount.limits.users) }}</td>
</tr>
</table>
</div>
<p class="settings-hint additional-top-margin" v-html="disclaimerHint" />
</div>
</template>
@ -90,6 +114,7 @@
import { loadState } from '@nextcloud/initial-state'
import axios from '@nextcloud/axios'
import { generateOcsUrl } from '@nextcloud/router'
import moment from '@nextcloud/moment'
export default {
name: 'HostedSignalingServer',
@ -103,6 +128,8 @@ export default {
hostedHPBCountry: '',
requestError: '',
loading: false,
trailAccount: [],
}
},
@ -119,6 +146,28 @@ export default {
.replace('{linkstart}', '<a target="_blank" rel="noreferrer nofollow" class="external" href="https://www.spreed.eu/nextcloud-talk-high-performance-backend/">')
.replace('{linkend}', ' ↗</a>')
},
translatedStatus() {
switch (this.trailAccount.status) {
case 'pending':
return t('spreed', 'Pending')
case 'error':
return t('spreed', 'Error')
case 'blocked':
return t('spreed', 'Blocked')
case 'active':
return t('spreed', 'Active')
case 'expired':
return t('spreed', 'Expired')
}
return ''
},
expiryDate() {
return moment(this.trailAccount.expires).format('L')
},
createdDate() {
return moment(this.trailAccount.created).format('L')
},
},
beforeMount() {
@ -128,6 +177,8 @@ export default {
this.hostedHPBEmail = state.email
this.hostedHPBLanguage = state.language
this.hostedHPBCountry = state.country
this.trailAccount = loadState('talk', 'hosted_signaling_server_trial_data')
},
methods: {
@ -143,10 +194,7 @@ export default {
country: this.hostedHPBCountry,
})
// TODO all fine
this.trailAccount = res.data.ocs.data
} catch (err) {
this.requestError = err?.response?.data?.ocs?.data?.message || t('spreed', 'The trial could not be requested. Please try again later.')
} finally {
@ -162,4 +210,17 @@ export default {
margin-top: 10px;
}
td {
padding: 5px;
border-bottom: 1px solid var(--color-border);
}
tr:last-child td {
border-bottom: none;
}
tr :first-child {
opacity: .5;
}
</style>
Loading…
Cancel
Save