Skip to content

Commit 5a05931

Browse files
committed
[#12] WIP: Add SSO support
Fixes #12 REMOVE HTTPS CERT WORKAROUND BEFORE MERGE TO MASTER! MCC instance with SSO enabled for testing currently has invalid cert chain, so this is needed as a temporary workaround during development. Done: - Renamed existing `AuthProvider` to `BasicAuthProvider`. This provider will fail with an error notification if it's used with an MCC instance that requires SSO auth. - Added new `SsoAuthProvider` for handling all things SSO. This provider will fail with an error notification if it's used with an MCC instance that does not support Keycloak SSO auth. - Moved a few effects out of View.js and into useClusterLoder.js hook to cut down on module size. - Added 'SSO support' section to README with instructions on how to configure the MCC instance's Keycloak Client to work with the extension since it relies on `lens://` protocol handler requests. - Added new "Use SSO" checkbox in Login component. - Added new util.js method to make console logging more helpful and consistent, replaced all existing `console` calls with new `logger` calls.
1 parent c9370fd commit 5a05931

19 files changed

+739
-201
lines changed

README.md

+7-2
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,14 @@ The `prepublishOnly` script will automatically produce a production build in the
8080

8181
## Help
8282

83-
### SSO not supported
83+
### SSO support
8484

85-
Mirantis Container Cloud instances that use third-party SSO authentication (e.g. Google OAuth) are __not supported__ at this time. We plan on adding support [soon](https://github.com/Mirantis/lens-extension-cc/issues/12).
85+
Mirantis Container Cloud instances that use third-party SSO authentication via __Keycloak__ are supported.
86+
87+
Since the integration leverages the `lens://` URL protocol handling feature for extensions, __Lens 4.1__ is required, and the __Keycloak Client__ of the instance must be configured as follows:
88+
89+
- Allow requests from the `"*"` origin. This is because the internal Electron browser used by the Lens App uses a random port. Therefore, the originating URL cannot be predicted.
90+
- Allow the following redirect URI: `lens://extensions/@mirantis/lens-extension-cc/oauth/code`
8691

8792
### Management clusters not selected by default
8893

src/cc/Login.js

+44-26
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const Login = function ({ loading, disabled, onLogin, ...props }) {
3535
//
3636

3737
const [cloudUrl, setCloudUrl] = useState(props.cloudUrl || '');
38+
const [withSsoAuth, setWithSsoAuth] = useState(props.withSsoAuth || false);
3839
const [username, setUsername] = useState(props.username || '');
3940
const [password, setPassword] = useState(props.password || '');
4041
const [valid, setValid] = useState(false);
@@ -47,6 +48,10 @@ export const Login = function ({ loading, disabled, onLogin, ...props }) {
4748
setCloudUrl(value);
4849
};
4950

51+
const handleSsoChange = function (value) {
52+
setWithSsoAuth(value);
53+
};
54+
5055
const handleUsernameChange = function (value) {
5156
setUsername(value);
5257
};
@@ -56,7 +61,7 @@ export const Login = function ({ loading, disabled, onLogin, ...props }) {
5661
};
5762

5863
const handleClustersClick = function () {
59-
onLogin({ cloudUrl, username, password });
64+
onLogin({ cloudUrl, withSsoAuth, username, password });
6065
};
6166

6267
//
@@ -65,9 +70,9 @@ export const Login = function ({ loading, disabled, onLogin, ...props }) {
6570

6671
useEffect(
6772
function () {
68-
setValid(!!(cloudUrl && username && password));
73+
setValid(!!(cloudUrl && (withSsoAuth || (username && password))));
6974
},
70-
[username, password, cloudUrl]
75+
[username, password, cloudUrl, withSsoAuth]
7176
);
7277

7378
//
@@ -90,31 +95,42 @@ export const Login = function ({ loading, disabled, onLogin, ...props }) {
9095
/>
9196
</Field>
9297
<Field>
93-
<label htmlFor="lecc-login-username">
94-
{strings.login.username.label()}
95-
</label>
96-
<Component.Input
97-
type="text"
98-
theme="round-black" // borders on all sides, rounded corners
99-
id="lecc-login-username"
100-
disabled={loading}
101-
value={username}
102-
onChange={handleUsernameChange}
103-
/>
104-
</Field>
105-
<Field>
106-
<label htmlFor="lecc-login-password">
107-
{strings.login.password.label()}
108-
</label>
109-
<Component.Input
110-
type="password"
111-
theme="round-black" // borders on all sides, rounded corners
112-
id="lecc-login-password"
113-
disabled={loading}
114-
value={password}
115-
onChange={handlePasswordChange}
98+
<Component.Checkbox
99+
label={strings.login.sso.label()}
100+
value={withSsoAuth}
101+
onChange={handleSsoChange}
116102
/>
117103
</Field>
104+
{!withSsoAuth && (
105+
<>
106+
<Field>
107+
<label htmlFor="lecc-login-username">
108+
{strings.login.username.label()}
109+
</label>
110+
<Component.Input
111+
type="text"
112+
theme="round-black" // borders on all sides, rounded corners
113+
id="lecc-login-username"
114+
disabled={loading}
115+
value={username}
116+
onChange={handleUsernameChange}
117+
/>
118+
</Field>
119+
<Field>
120+
<label htmlFor="lecc-login-password">
121+
{strings.login.password.label()}
122+
</label>
123+
<Component.Input
124+
type="password"
125+
theme="round-black" // borders on all sides, rounded corners
126+
id="lecc-login-password"
127+
disabled={loading}
128+
value={password}
129+
onChange={handlePasswordChange}
130+
/>
131+
</Field>
132+
</>
133+
)}
118134
<div>
119135
<Component.Button
120136
primary
@@ -124,6 +140,7 @@ export const Login = function ({ loading, disabled, onLogin, ...props }) {
124140
onClick={handleClustersClick}
125141
/>
126142
</div>
143+
{withSsoAuth && loading && <p>{strings.login.sso.browser()}</p>}
127144
</Section>
128145
);
129146
};
@@ -133,6 +150,7 @@ Login.propTypes = {
133150
loading: propTypes.bool, // if data fetch related to login is taking place
134151
disabled: propTypes.bool, // if login should be disabled entirely
135152
cloudUrl: propTypes.string,
153+
withSsoAuth: propTypes.bool,
136154
username: propTypes.string,
137155
password: propTypes.string,
138156
};

0 commit comments

Comments
 (0)