working onelogin auth implementation
This commit is contained in:
@@ -21,6 +21,7 @@ import {
|
||||
githubAuthApiRef,
|
||||
samlAuthApiRef,
|
||||
microsoftAuthApiRef,
|
||||
oneloginAuthApiRef,
|
||||
} from '@backstage/core';
|
||||
|
||||
export const providers = [
|
||||
@@ -60,4 +61,10 @@ export const providers = [
|
||||
message: 'Sign In using SAML',
|
||||
apiRef: samlAuthApiRef,
|
||||
},
|
||||
{
|
||||
id: 'onelogin-auth-provider',
|
||||
title: 'OneLogin',
|
||||
message: 'Sign In using OneLogin',
|
||||
apiRef: oneloginAuthApiRef,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -320,3 +320,14 @@ export const samlAuthApiRef: ApiRef<
|
||||
id: 'core.auth.saml',
|
||||
description: 'Example of how to use SAML custom provider',
|
||||
});
|
||||
|
||||
export const oneloginAuthApiRef: ApiRef<
|
||||
OAuthApi &
|
||||
OpenIdConnectApi &
|
||||
ProfileInfoApi &
|
||||
BackstageIdentityApi &
|
||||
SessionApi
|
||||
> = createApiRef({
|
||||
id: 'core.auth.onelogin',
|
||||
description: 'Provides authentication towards OneLogin APIs and identities',
|
||||
});
|
||||
|
||||
@@ -22,3 +22,4 @@ export * from './okta';
|
||||
export * from './saml';
|
||||
export * from './auth0';
|
||||
export * from './microsoft';
|
||||
export * from './onelogin';
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import OktaAuth from './OktaAuth';
|
||||
import MockOAuthApi from '../../OAuthRequestApi/MockOAuthApi';
|
||||
import { UrlPatternDiscovery } from '../../DiscoveryApi';
|
||||
|
||||
const PREFIX = 'okta.';
|
||||
|
||||
const getSession = jest.fn();
|
||||
|
||||
jest.mock('../../../../lib/AuthSessionManager', () => ({
|
||||
...(jest.requireActual('../../../../lib/AuthSessionManager') as any),
|
||||
RefreshingAuthSessionManager: class {
|
||||
getSession = getSession;
|
||||
},
|
||||
}));
|
||||
|
||||
describe('OktaAuth', () => {
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
it.each([
|
||||
['openid', ['openid']],
|
||||
['profile email', ['profile', 'email']],
|
||||
[`${PREFIX}groups.manage`, [`${PREFIX}groups.manage`]],
|
||||
['groups.read', [`${PREFIX}groups.read`]],
|
||||
[
|
||||
`${PREFIX}groups.manage groups.read, openid`,
|
||||
[`${PREFIX}groups.manage`, `${PREFIX}groups.read`, 'openid'],
|
||||
],
|
||||
[`email\t ${PREFIX}groups.read`, ['email', `${PREFIX}groups.read`]],
|
||||
|
||||
// Some incorrect scopes that we don't try to fix
|
||||
[`${PREFIX}email`, [`${PREFIX}email`]],
|
||||
[`${PREFIX}profile`, [`${PREFIX}profile`]],
|
||||
[`${PREFIX}openid`, [`${PREFIX}openid`]],
|
||||
])(`should normalize scopes correctly - %p`, (scope, scopes) => {
|
||||
const auth = OktaAuth.create({
|
||||
oauthRequestApi: new MockOAuthApi(),
|
||||
discoveryApi: UrlPatternDiscovery.compile('http://example.com'),
|
||||
});
|
||||
|
||||
auth.getAccessToken(scope);
|
||||
expect(getSession).toHaveBeenCalledWith({ scopes: new Set(scopes) });
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import OneLoginIcon from '@material-ui/icons/AcUnit';
|
||||
import { oneloginAuthApiRef } from '@backstage/core-api/src/apis/definitions/auth';
|
||||
import {
|
||||
OAuthRequestApi,
|
||||
AuthProvider,
|
||||
DiscoveryApi,
|
||||
} from '@backstage/core-api/src/apis/definitions';
|
||||
import { OAuth2 } from '@backstage/core-api/src/apis/implementations/auth/oauth2';
|
||||
|
||||
type CreateOptions = {
|
||||
discoveryApi: DiscoveryApi;
|
||||
oauthRequestApi: OAuthRequestApi;
|
||||
|
||||
environment?: string;
|
||||
provider?: AuthProvider & { id: string };
|
||||
};
|
||||
|
||||
const DEFAULT_PROVIDER = {
|
||||
id: 'onelogin',
|
||||
title: 'onelogin',
|
||||
icon: OneLoginIcon,
|
||||
};
|
||||
|
||||
const OIDC_SCOPES: Set<String> = new Set([
|
||||
'openid',
|
||||
'profile',
|
||||
'email',
|
||||
'phone',
|
||||
'address',
|
||||
'groups',
|
||||
'offline_access',
|
||||
]);
|
||||
|
||||
const SCOPE_PREFIX: string = 'onelogin.';
|
||||
|
||||
class OneLoginAuth {
|
||||
static create({
|
||||
discoveryApi,
|
||||
environment = 'development',
|
||||
provider = DEFAULT_PROVIDER,
|
||||
oauthRequestApi,
|
||||
}: CreateOptions): typeof oneloginAuthApiRef.T {
|
||||
return OAuth2.create({
|
||||
discoveryApi,
|
||||
oauthRequestApi,
|
||||
provider,
|
||||
environment,
|
||||
defaultScopes: ['openid', 'email', 'profile', 'offline_access'],
|
||||
scopeTransform(scopes) {
|
||||
return scopes.map(scope => {
|
||||
if (OIDC_SCOPES.has(scope)) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
if (scope.startsWith(SCOPE_PREFIX)) {
|
||||
return scope;
|
||||
}
|
||||
|
||||
return `${SCOPE_PREFIX}${scope}`;
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default OneLoginAuth;
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export { default as OneLoginAuth } from './OneLoginAuth';
|
||||
@@ -44,6 +44,8 @@ import {
|
||||
UrlPatternDiscovery,
|
||||
samlAuthApiRef,
|
||||
SamlAuth,
|
||||
oneloginAuthApiRef,
|
||||
OneLoginAuth,
|
||||
} from '@backstage/core-api';
|
||||
|
||||
export const defaultApis = [
|
||||
@@ -142,4 +144,13 @@ export const defaultApis = [
|
||||
},
|
||||
factory: ({ discoveryApi }) => SamlAuth.create({ discoveryApi }),
|
||||
}),
|
||||
createApiFactory({
|
||||
api: oneloginAuthApiRef,
|
||||
deps: {
|
||||
discoveryApi: discoveryApiRef,
|
||||
oauthRequestApi: oauthRequestApiRef,
|
||||
},
|
||||
factory: ({ discoveryApi, oauthRequestApi }) =>
|
||||
OneLoginAuth.create({ discoveryApi, oauthRequestApi }),
|
||||
}),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user