Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] Improve cloud section #13820

Merged
merged 10 commits into from
Apr 2, 2019
40 changes: 28 additions & 12 deletions app/cloud/client/admin/cloud.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,41 @@
</div>
</div>
<div class="section">
{{#if info.registeredWithWizard}}
{{#if info.workspaceConnected}}
{{#if info.connectToCloud}}
{{#if info.workspaceRegistered}}
<div class="section-content border-component-color">
{{#if info.userAssociated}}
<p>{{_ "Cloud_workspace_connected_plus_account"}}</p>
{{else}}
<p>{{_ "Cloud_workspace_connected_without_account"}}</p>
<p>{{_ "Cloud_workspace_connected"}}</p>
<div class="input-line double-col">
<label class="setting-label" title=""></label>
<div class="setting-field">
<a href="https://cloud.rocket.chat" class="rc-button rc-button--primary" target="_blank">{{_ "Cloud_login_to_cloud"}}</a>
</div>
</div>
</div>

<div class="section-content border-component-color">
<p>{{_ "Cloud_workspace_support"}}</p>
<div class="input-line double-col">
<label class="setting-label" title=""></label>
<div class="setting-field">
<button type="button" class="rc-button rc-button--primary action login-btn">{{_ "Cloud_login_to_cloud"}}</button>
<button type="button" class="rc-button rc-button--danger action sync-btn">{{_ "Sync"}}</button>
</div>
</div>
{{/if}}
</div>

<div class="section-content border-component-color">
<p>{{_ "Cloud_workspace_disconnect"}}</p>
<div class="input-line double-col">
<label class="setting-label" title=""></label>
<div class="setting-field">
<button type="button" class="rc-button rc-button--danger action disconnect-btn">{{_ "Disconnect"}}</button>
</div>
</div>
</div>
{{else}}
<div class="section-content border-component-color">
<div class="input-line double-col">
<label class="setting-label" title="cloudEmail">Email</label>
<label class="setting-label" title="cloudEmail">{{_ "Email"}}</label>
<div class="setting-field">
<input class="input-monitor rc-input__element" type="text" name="cloudEmail" value="{{ info.email }}">
<div class="settings-description secondary-font-color">{{_ "Cloud_address_to_send_registration_to"}}</div>
Expand All @@ -47,8 +63,6 @@
</div>
</div>

<pre>{{ registeredWithWizard }}</pre>

<div class="input-line double-col">
<label class="setting-label" title="cloudToken">{{_ "Token"}}</label>
<div class="setting-field">
Expand All @@ -62,6 +76,8 @@
<button type="button" class="rc-button rc-button--primary action connect-btn">{{_ "Connect"}}</button>
</div>
</div>

<p>If you still haven't received a registration email please make sure your email is updated above. If you still have issues you can contact support at: <a href="mailto:support@rocket.chat?subject=[Self Hosted Registration]&body=WorkspaceId: {{ info.workspaceId }}%0D%0ADeployment Id: {{ info.uniqueId }}%0D%0AIssue: <please describe your issue here>">support@rocket.chat</a></p>
</div>
{{/if}}
{{else}}
Expand All @@ -72,7 +88,7 @@
</div>
<div class="section-content border-component-color">
<p>{{_ "Cloud_registration_required_description"}}</p>
<p><a href="./admin/Setup_Wizard">{{_ "Cloud_registration_requried_link_text"}}</a></p>
<button type="button" class="rc-button rc-button--primary action register-btn">{{_ "Cloud_registration_requried_link_text"}}</button>
</div>
{{/if}}
</div>
Expand Down
85 changes: 73 additions & 12 deletions app/cloud/client/admin/cloud.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,67 @@ Template.cloud.onCreated(function() {
}

if (!success) {
toastr.error('Invalid token');
toastr.error('An error occured connecting');
instance.loadRegStatus();
return;
}

toastr.success(t('Connected'));

instance.loadRegStatus();
});
};

instance.disconnectWorkspace = function _disconnectWorkspace() {
Meteor.call('cloud:disconnectWorkspace', (error, success) => {
if (error) {
toastr.error(error);
instance.loadRegStatus();
return;
}

if (!success) {
toastr.error('An error occured disconnecting');
instance.loadRegStatus();
return;
}

toastr.success(t('Disconnected'));

instance.loadRegStatus();
});
};

instance.syncWorkspace = function _syncWorkspace() {
Meteor.call('cloud:syncWorkspace', (error, success) => {
if (error) {
toastr.error(error);
instance.loadRegStatus();
return;
}

if (!success) {
toastr.error('An error occured syncing');
instance.loadRegStatus();
return;
}

toastr.success(t('Sync Complete'));

instance.loadRegStatus();
});
};

instance.registerWorkspace = function _registerWorkspace() {
Meteor.call('cloud:registerWorkspace', (error, success) => {
if (error) {
toastr.error(error);
instance.loadRegStatus();
return;
}

if (!success) {
toastr.error('An error occured');
instance.loadRegStatus();
return;
}
Expand Down Expand Up @@ -74,20 +134,21 @@ Template.cloud.events({
});
},

'click .login-btn'() {
Meteor.call('cloud:getOAuthAuthorizationUrl', (error, url) => {
if (error) {
console.warn(error);
return;
}

window.location.href = url;
});
},

'click .connect-btn'(e, i) {
const token = $('input[name=cloudToken]').val();

i.connectWorkspace(token);
},

'click .register-btn'(e, i) {
i.registerWorkspace();
},

'click .disconnect-btn'(e, i) {
i.disconnectWorkspace();
},

'click .sync-btn'(e, i) {
i.syncWorkspace();
},
});
8 changes: 5 additions & 3 deletions app/cloud/server/functions/connectWorkspace.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ import { Settings } from '../../../models';

import { getRedirectUri } from './getRedirectUri';
import { retrieveRegistrationStatus } from './retrieveRegistrationStatus';
import { workspaceScopes } from '../oauthScopes';

export function connectWorkspace(token) {
const { registeredWithWizard } = retrieveRegistrationStatus();
if (!registeredWithWizard) {
return false;
const { connectToCloud } = retrieveRegistrationStatus();
if (!connectToCloud) {
Settings.updateValueById('Register_Server', true);
}

const redirectUri = getRedirectUri();
Expand Down Expand Up @@ -56,6 +57,7 @@ export function connectWorkspace(token) {
client_id: data.client_id,
client_secret: data.client_secret,
grant_type: 'client_credentials',
scope: workspaceScopes.join(' '),
redirect_uri: redirectUri,
}),
});
Expand Down
13 changes: 13 additions & 0 deletions app/cloud/server/functions/disconnectWorkspace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { retrieveRegistrationStatus } from './retrieveRegistrationStatus';
import { Settings } from '../../../models';

export function disconnectWorkspace() {
const { connectToCloud } = retrieveRegistrationStatus();
if (!connectToCloud) {
return true;
}

Settings.updateValueById('Register_Server', false);

return true;
}
4 changes: 4 additions & 0 deletions app/cloud/server/functions/finishOAuthAuthorization.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { settings } from '../../../settings';
import { Settings, Users } from '../../../models';

import { getRedirectUri } from './getRedirectUri';
import { userScopes } from '../oauthScopes';

export function finishOAuthAuthorization(code, state) {
if (settings.get('Cloud_Workspace_Registration_State') !== state) {
Expand All @@ -16,6 +17,8 @@ export function finishOAuthAuthorization(code, state) {
const clientId = settings.get('Cloud_Workspace_Client_Id');
const clientSecret = settings.get('Cloud_Workspace_Client_Secret');

const scope = userScopes.join(' ');

let result;
try {
result = HTTP.post(`${ cloudUrl }/api/oauth/token`, {
Expand All @@ -24,6 +27,7 @@ export function finishOAuthAuthorization(code, state) {
client_id: clientId,
client_secret: clientSecret,
grant_type: 'authorization_code',
scope,
code,
redirect_uri: getRedirectUri(),
}),
Expand Down
5 changes: 4 additions & 1 deletion app/cloud/server/functions/getOAuthAuthorizationUrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Settings } from '../../../models';
import { settings } from '../../../settings';

import { getRedirectUri } from './getRedirectUri';
import { userScopes } from '../oauthScopes';

export function getOAuthAuthorizationUrl() {
const state = Random.id();
Expand All @@ -13,5 +14,7 @@ export function getOAuthAuthorizationUrl() {
const client_id = settings.get('Cloud_Workspace_Client_Id');
const redirectUri = getRedirectUri();

return `${ cloudUrl }/authorize?response_type=code&client_id=${ client_id }&redirect_uri=${ redirectUri }&scope=offline_access&state=${ state }`;
const scope = userScopes.join(' ');

return `${ cloudUrl }/authorize?response_type=code&client_id=${ client_id }&redirect_uri=${ redirectUri }&scope=${ scope }&state=${ state }`;
}
32 changes: 24 additions & 8 deletions app/cloud/server/functions/getWorkspaceAccessToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@ import { settings } from '../../../settings';
import { Settings } from '../../../models';

import { getRedirectUri } from './getRedirectUri';
import { retrieveRegistrationStatus } from './retrieveRegistrationStatus';
import { unregisterWorkspace } from './unregisterWorkspace';
import { workspaceScopes } from '../oauthScopes';

export function getWorkspaceAccessToken() {
if (!settings.get('Register_Server')) {
export function getWorkspaceAccessToken(forceNew = false, scope = '', save = true) {
const { connectToCloud, workspaceRegistered } = retrieveRegistrationStatus();

if (!connectToCloud || !workspaceRegistered) {
return '';
}

Expand All @@ -19,35 +24,46 @@ export function getWorkspaceAccessToken() {
const expires = Settings.findOneById('Cloud_Workspace_Access_Token_Expires_At');
const now = new Date();

if (now < expires.value) {
if (now < expires.value && !forceNew) {
return settings.get('Cloud_Workspace_Access_Token');
}

const cloudUrl = settings.get('Cloud_Url');
const client_secret = settings.get('Cloud_Workspace_Client_Secret');
const redirectUri = getRedirectUri();

if (scope === '') {
scope = workspaceScopes.join(' ');
}

let authTokenResult;
try {
authTokenResult = HTTP.post(`${ cloudUrl }/api/oauth/token`, {
data: {},
query: querystring.stringify({
client_id,
client_secret,
scope,
grant_type: 'client_credentials',
redirect_uri: redirectUri,
}),
});
} catch (e) {
if (e.response && e.response.data && e.response.data.errorCode === 'oauth_invalid_client_credentials') {
console.error('Server has been unregistered from cloud');
unregisterWorkspace();
}

return '';
}

const expiresAt = new Date();
expiresAt.setSeconds(expiresAt.getSeconds() + authTokenResult.data.expires_in);

Settings.updateValueById('Cloud_Workspace_Access_Token', authTokenResult.data.access_token);
Settings.updateValueById('Cloud_Workspace_Access_Token_Expires_At', expiresAt);
if (save) {
const expiresAt = new Date();
expiresAt.setSeconds(expiresAt.getSeconds() + authTokenResult.data.expires_in);

Settings.updateValueById('Cloud_Workspace_Access_Token', authTokenResult.data.access_token);
Settings.updateValueById('Cloud_Workspace_Access_Token_Expires_At', expiresAt);
}

return authTokenResult.data.access_token;
}
6 changes: 4 additions & 2 deletions app/cloud/server/functions/retrieveRegistrationStatus.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import { Users } from '../../../models';

export function retrieveRegistrationStatus() {
const info = {
registeredWithWizard: settings.get('Register_Server'),
workspaceConnected: (settings.get('Cloud_Workspace_Client_Id')) ? true : false,
connectToCloud: settings.get('Register_Server'),
workspaceRegistered: (settings.get('Cloud_Workspace_Client_Id')) ? true : false,
userAssociated: (settings.get('Cloud_Workspace_Account_Associated')) ? true : false,
workspaceId: settings.get('Cloud_Workspace_Id'),
uniqueId: settings.get('uniqueID'),
token: '',
email: '',
};
Expand Down
Loading