[NEW] Custom OAuth (#1093)

This commit is contained in:
Johannes Buechele 2019-08-07 16:36:54 +02:00 committed by Diego Mello
parent ba232547f1
commit 6a3523d6bf
3 changed files with 55 additions and 26 deletions

View File

@ -778,13 +778,19 @@ const RocketChat = {
try {
let loginServicesFilter = [];
const loginServicesResult = await fetch(`${ server }/api/v1/settings.oauth`).then(response => response.json());
// TODO: remove this after SAML and custom oauth
const availableOAuth = ['facebook', 'github', 'gitlab', 'google', 'linkedin', 'meteor-developer', 'twitter'];
if (loginServicesResult.success && loginServicesResult.services.length > 0) {
const { services } = loginServicesResult;
loginServicesFilter = services.filter(item => availableOAuth.includes(item.name));
loginServicesFilter = services.filter(item => item.custom !== undefined); // TODO: remove this after SAML and CAS
const loginServicesReducer = loginServicesFilter.reduce((ret, item) => {
ret[item.name] = item;
const name = item.name ? item.name : item.service;
const authType = this._determineAuthType(item);
if (authType !== 'not_supported') {
ret[name] = { ...item, name, authType };
}
return ret;
}, {});
reduxStore.dispatch(setLoginServices(loginServicesReducer));
@ -795,6 +801,17 @@ const RocketChat = {
return Promise.reject();
}
},
_determineAuthType(service) {
// TODO: remove this after other oauth providers are implemented. e.g. Drupal, github_enterprise
const availableOAuth = ['facebook', 'github', 'gitlab', 'google', 'linkedin', 'meteor-developer', 'twitter'];
const { name, custom } = service;
if (custom) {
return 'oauth_custom';
}
return availableOAuth.includes(name) ? 'oauth' : 'not_supported';
},
getUsernameSuggestion() {
// RC 0.65.0
return this.sdk.get('users.getUsernameSuggestion');

View File

@ -51,7 +51,6 @@ export default function login(state = initialState, action) {
return {
...state,
services: {
...state.services,
...action.data
}
};

View File

@ -221,6 +221,18 @@ class LoginSignupView extends React.Component {
this.openOAuth(url);
}
onPressCustomOAuth = (loginService) => {
const { server } = this.props;
const {
serverURL, authorizePath, clientId, scope, service
} = loginService;
const redirectUri = `${ server }/_oauth/${ service }`;
const state = this.getOAuthState();
const params = `?client_id=${ clientId }&redirect_uri=${ redirectUri }&response_type=code&state=${ state }&scope=${ scope }`;
const url = `${ serverURL }${ authorizePath }${ params }`;
this.openOAuth(url);
}
getOAuthState = () => {
const credentialToken = random(43);
return Base64.encodeURI(JSON.stringify({ loginStyle: 'popup', credentialToken, isCordova: true }));
@ -265,6 +277,19 @@ class LoginSignupView extends React.Component {
this.setState(prevState => ({ collapsed: !prevState.collapsed }));
}
getSocialOauthProvider = (name) => {
const oauthProviders = {
facebook: this.onPressFacebook,
github: this.onPressGithub,
gitlab: this.onPressGitlab,
google: this.onPressGoogle,
linkedin: this.onPressLinkedin,
'meteor-developer': this.onPressMeteor,
twitter: this.onPressTwitter
};
return oauthProviders[name];
}
renderServicesSeparator = () => {
const { collapsed } = this.state;
const { services } = this.props;
@ -294,35 +319,23 @@ class LoginSignupView extends React.Component {
const icon = `icon_${ name }`;
name = name.charAt(0).toUpperCase() + name.slice(1);
let onPress = () => {};
switch (service.name) {
case 'facebook':
onPress = this.onPressFacebook;
switch (service.authType) {
case 'oauth': {
onPress = this.getSocialOauthProvider(service.name);
break;
case 'github':
onPress = this.onPressGithub;
break;
case 'gitlab':
onPress = this.onPressGitlab;
break;
case 'google':
onPress = this.onPressGoogle;
break;
case 'linkedin':
onPress = this.onPressLinkedin;
break;
case 'meteor-developer':
onPress = this.onPressMeteor;
break;
case 'twitter':
onPress = this.onPressTwitter;
}
case 'oauth_custom': {
onPress = () => this.onPressCustomOAuth(service);
break;
}
default:
break;
}
return (
<RectButton key={service.name} onPress={onPress} style={styles.serviceButton}>
<View style={styles.serviceButtonContainer}>
<Image source={{ uri: icon }} style={styles.serviceIcon} />
{service.authType === 'oauth' ? <Image source={{ uri: icon }} style={styles.serviceIcon} /> : null}
<Text style={styles.serviceText}>
{I18n.t('Continue_with')} <Text style={styles.serviceName}>{name}</Text>
</Text>