[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 { try {
let loginServicesFilter = []; let loginServicesFilter = [];
const loginServicesResult = await fetch(`${ server }/api/v1/settings.oauth`).then(response => response.json()); 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) { if (loginServicesResult.success && loginServicesResult.services.length > 0) {
const { services } = loginServicesResult; 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) => { 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; return ret;
}, {}); }, {});
reduxStore.dispatch(setLoginServices(loginServicesReducer)); reduxStore.dispatch(setLoginServices(loginServicesReducer));
@ -795,6 +801,17 @@ const RocketChat = {
return Promise.reject(); 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() { getUsernameSuggestion() {
// RC 0.65.0 // RC 0.65.0
return this.sdk.get('users.getUsernameSuggestion'); return this.sdk.get('users.getUsernameSuggestion');

View File

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

View File

@ -221,6 +221,18 @@ class LoginSignupView extends React.Component {
this.openOAuth(url); 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 = () => { getOAuthState = () => {
const credentialToken = random(43); const credentialToken = random(43);
return Base64.encodeURI(JSON.stringify({ loginStyle: 'popup', credentialToken, isCordova: true })); 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 })); 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 = () => { renderServicesSeparator = () => {
const { collapsed } = this.state; const { collapsed } = this.state;
const { services } = this.props; const { services } = this.props;
@ -294,35 +319,23 @@ class LoginSignupView extends React.Component {
const icon = `icon_${ name }`; const icon = `icon_${ name }`;
name = name.charAt(0).toUpperCase() + name.slice(1); name = name.charAt(0).toUpperCase() + name.slice(1);
let onPress = () => {}; let onPress = () => {};
switch (service.name) {
case 'facebook': switch (service.authType) {
onPress = this.onPressFacebook; case 'oauth': {
onPress = this.getSocialOauthProvider(service.name);
break; break;
case 'github': }
onPress = this.onPressGithub; case 'oauth_custom': {
break; onPress = () => this.onPressCustomOAuth(service);
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;
break; break;
}
default: default:
break; break;
} }
return ( return (
<RectButton key={service.name} onPress={onPress} style={styles.serviceButton}> <RectButton key={service.name} onPress={onPress} style={styles.serviceButton}>
<View style={styles.serviceButtonContainer}> <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}> <Text style={styles.serviceText}>
{I18n.t('Continue_with')} <Text style={styles.serviceName}>{name}</Text> {I18n.t('Continue_with')} <Text style={styles.serviceName}>{name}</Text>
</Text> </Text>