forked from metabase/metabase
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Google Auth 🔒 [wip] [ci skip] * "No Metabase account exists for this Google account" screen 😋 * Single Sign On Settings Page [WIP] 😋 * Google Auth v1 🔒 * update login layout * add setup instructions * add google logo for google account signups * clean up sso form layout * Merge branch 'master' into google-auth [ci skip] * Fix Google Auth button not showing up after initial load 🔒 * Fix bug when creating session for user with no last_login 🔒 * Organize google auth backend code a bit 🔒 * Lots of tests for Google Auth 🔏 * Add Save Button to Google Auth settings page 🔒 * Use onChange instead of onBlurChange 🔒 * Make "save changes" button say "changes saved" after save 🔏 * adjust user settings for managed accounts * Ensure we clear GA creds if GA login fails * tweak password reset email * owned google sign in button * use var * Cleanup some random legacy Angular junk * Keep Redux and AppState currentUser in sync, fixes login issue * render() should have side-effects! Fixes $digest errors on logout * Test fixes 🔧 * fix checkbox * cleanup * remove unused import
- Loading branch information
Showing
44 changed files
with
733 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
frontend/src/metabase/admin/settings/components/SettingsSingleSignOnForm.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
import React, { Component, PropTypes } from "react"; | ||
|
||
import cx from "classnames"; | ||
import _ from "underscore"; | ||
|
||
import Input from "metabase/components/Input.jsx"; | ||
|
||
export default class SettingsSingleSignOnForm extends Component { | ||
constructor(props, context) { | ||
super(props, context); | ||
this.updateClientID = this.updateClientID.bind(this); | ||
this.updateDomain = this.updateDomain.bind(this); | ||
this.onCheckboxClicked = this.onCheckboxClicked.bind(this), | ||
this.saveChanges = this.saveChanges.bind(this), | ||
this.clientIDChanged = this.clientIDChanged.bind(this), | ||
this.domainChanged = this.domainChanged.bind(this) | ||
} | ||
|
||
static propTypes = { | ||
elements: PropTypes.array, | ||
updateSetting: PropTypes.func.isRequired | ||
}; | ||
|
||
componentWillMount() { | ||
let { elements } = this.props, | ||
clientID = _.findWhere(elements, {key: 'google-auth-client-id'}), | ||
domain = _.findWhere(elements, {key: 'google-auth-auto-create-accounts-domain'}); | ||
|
||
this.setState({ | ||
clientID: clientID, | ||
domain: domain, | ||
clientIDValue: clientID.value, | ||
domainValue: domain.value, | ||
recentlySaved: false | ||
}); | ||
} | ||
|
||
updateClientID(newValue) { | ||
if (newValue === this.state.clientIDValue) return; | ||
|
||
this.setState({ | ||
clientIDValue: newValue && newValue.length ? newValue : null, | ||
recentlySaved: false | ||
}); | ||
} | ||
|
||
updateDomain(newValue) { | ||
if (newValue === this.state.domain.value) return; | ||
|
||
this.setState({ | ||
domainValue: newValue && newValue.length ? newValue : null, | ||
recentlySaved: false | ||
}); | ||
} | ||
|
||
clientIDChanged() { | ||
return this.state.clientID.value !== this.state.clientIDValue; | ||
} | ||
|
||
domainChanged() { | ||
return this.state.domain.value !== this.state.domainValue; | ||
} | ||
|
||
saveChanges() { | ||
let { clientID, clientIDValue, domain, domainValue } = this.state; | ||
|
||
if (this.clientIDChanged()) { | ||
this.props.updateSetting(clientID, clientIDValue); | ||
this.setState({ | ||
clientID: { | ||
value: clientIDValue | ||
}, | ||
recentlySaved: true | ||
}); | ||
} | ||
|
||
if (this.domainChanged()) { | ||
this.props.updateSetting(domain, domainValue); | ||
this.setState({ | ||
domain: { | ||
value: domainValue | ||
}, | ||
recentlySaved: true | ||
}); | ||
} | ||
} | ||
|
||
onCheckboxClicked() { | ||
// if domain is present, clear it out; otherwise if there's no domain try to set it back to what it was | ||
this.setState({ | ||
domainValue: this.state.domainValue ? null : this.state.domain.value, | ||
recentlySaved: false | ||
}); | ||
} | ||
|
||
render() { | ||
let hasChanges = this.domainChanged() || this.clientIDChanged(), | ||
hasClientID = this.state.clientIDValue; | ||
|
||
return ( | ||
<form noValidate> | ||
<div className="px2" | ||
style={{maxWidth: "585px"}}> | ||
<h2>Sign in with Google</h2> | ||
<p className="text-grey-4"> | ||
Allows users with existing Metabase accounts to login with a Google account that matches their email address in addition to their Metabase username and password. | ||
</p> | ||
<p className="text-grey-4"> | ||
To allow users to sign in with Google you'll need to give Metabase a Google Developers console application client ID. It only takes a few steps and instructions on how to create a key can be found <a className="link" href="https://developers.google.com/identity/sign-in/web/devconsole-project" target="_blank">here.</a> | ||
</p> | ||
<Input | ||
className="SettingsInput AdminInput bordered rounded h3" | ||
type="text" | ||
value={this.state.clientIDValue} | ||
placeholder="Your Google client ID" | ||
onChange={(event) => this.updateClientID(event.target.value)} | ||
/> | ||
<div className="py3"> | ||
<div className="flex align-center"> | ||
<p className="text-grey-4">Allow users to sign up on their own if their Google account email address is from:</p> | ||
</div> | ||
<div className="mt1 bordered rounded inline-block"> | ||
<div className="inline-block px2 h2">@</div> | ||
<Input | ||
className="SettingsInput inline-block AdminInput h3 border-left" | ||
type="text" | ||
value={this.state.domainValue} | ||
onChange={(event) => this.updateDomain(event.target.value)} | ||
disabled={!hasClientID} | ||
/> | ||
</div> | ||
</div> | ||
|
||
<button className={cx("Button mr2", {"Button--primary": hasChanges})} | ||
disabled={!hasChanges} | ||
onClick={this.saveChanges}> | ||
{this.state.recentlySaved ? "Changes saved!" : "Save Changes"} | ||
</button> | ||
</div> | ||
</form> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import React from 'react' | ||
|
||
const BackToLogin = () => | ||
<a className="link block" href="/auth/login">Back to login</a> | ||
|
||
export default BackToLogin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import React from "react"; | ||
|
||
import AuthScene from "./AuthScene.jsx"; | ||
import LogoIcon from "metabase/components/LogoIcon.jsx"; | ||
import BackToLogin from "./BackToLogin.jsx" | ||
|
||
const GoogleNoAccount = () => | ||
<div className="full-height bg-white flex flex-column flex-full md-layout-centered"> | ||
<div className="wrapper"> | ||
<div className="Login-wrapper Grid Grid--full md-Grid--1of2"> | ||
<div className="Grid-cell flex layout-centered text-brand"> | ||
<LogoIcon className="Logo my4 sm-my0" width={66} height={85} /> | ||
</div> | ||
<div className="Grid-cell text-centered bordered rounded shadowed p4"> | ||
<h3 className="mt4 mb2">No Metabase account exists for this Google account.</h3> | ||
<p className="mb4 ml-auto mr-auto" style={{maxWidth: 360}}> | ||
You'll need an administrator to create a Metabase account before | ||
you can use Google to log in. | ||
</p> | ||
|
||
<BackToLogin /> | ||
</div> | ||
</div> | ||
</div> | ||
<AuthScene /> | ||
</div> | ||
|
||
export default GoogleNoAccount; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import React, { Component, PropTypes } from "react"; | ||
import Icon from "metabase/components/Icon"; | ||
import { capitalize } from 'humanize' | ||
|
||
const propTypes = { | ||
provider: PropTypes.string.isRequired | ||
}; | ||
|
||
class SSOLoginButton extends Component { | ||
render () { | ||
const { provider } = this.props | ||
return ( | ||
<div className="relative z2 bg-white p2 cursor-pointer shadow-hover text-centered sm-text-left rounded block sm-inline-block bordered shadowed"> | ||
<div className="flex align-center"> | ||
<Icon className="mr1" name={provider} /> | ||
<h4>{`Sign in with ${capitalize(provider)}`}</h4> | ||
</div> | ||
</div> | ||
) | ||
} | ||
} | ||
|
||
|
||
SSOLoginButton.proptypes = propTypes | ||
|
||
export default SSOLoginButton; |
Oops, something went wrong.