Create ServerPermissionClient and add it to example backend
Signed-off-by: Joon Park <joonp@spotify.com>
This commit is contained in:
@@ -39,6 +39,9 @@
|
||||
"@backstage/plugin-jenkins-backend": "^0.1.9",
|
||||
"@backstage/plugin-kubernetes-backend": "^0.4.0",
|
||||
"@backstage/plugin-kafka-backend": "^0.2.12",
|
||||
"@backstage/plugin-permission-backend": "^0.1.0",
|
||||
"@backstage/plugin-permission-common": "^0.2.0",
|
||||
"@backstage/plugin-permission-node": "^0.2.0",
|
||||
"@backstage/plugin-proxy-backend": "^0.2.14",
|
||||
"@backstage/plugin-rollbar-backend": "^0.1.16",
|
||||
"@backstage/plugin-scaffolder-backend": "^0.15.17",
|
||||
|
||||
@@ -55,13 +55,20 @@ import graphql from './plugins/graphql';
|
||||
import app from './plugins/app';
|
||||
import badges from './plugins/badges';
|
||||
import jenkins from './plugins/jenkins';
|
||||
import permission from './plugins/permission';
|
||||
import { PluginEnvironment } from './types';
|
||||
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
|
||||
|
||||
function makeCreateEnv(config: Config) {
|
||||
const root = getRootLogger();
|
||||
const reader = UrlReaders.default({ logger: root, config });
|
||||
const discovery = SingleHostDiscovery.fromConfig(config);
|
||||
const tokenManager = ServerTokenManager.noop();
|
||||
const tokenManager = ServerTokenManager.fromConfig(config);
|
||||
const permissions = new ServerPermissionClient({
|
||||
discoveryApi: discovery,
|
||||
configApi: config,
|
||||
serverTokenManager: tokenManager,
|
||||
});
|
||||
|
||||
root.info(`Created UrlReader ${reader}`);
|
||||
|
||||
@@ -72,7 +79,16 @@ function makeCreateEnv(config: Config) {
|
||||
const logger = root.child({ type: 'plugin', plugin });
|
||||
const database = databaseManager.forPlugin(plugin);
|
||||
const cache = cacheManager.forPlugin(plugin);
|
||||
return { logger, cache, database, config, reader, discovery, tokenManager };
|
||||
return {
|
||||
logger,
|
||||
cache,
|
||||
database,
|
||||
config,
|
||||
reader,
|
||||
discovery,
|
||||
tokenManager,
|
||||
permissions,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -113,6 +129,7 @@ async function main() {
|
||||
const techInsightsEnv = useHotMemoize(module, () =>
|
||||
createEnv('tech-insights'),
|
||||
);
|
||||
const permissionEnv = useHotMemoize(module, () => createEnv('permission'));
|
||||
|
||||
const apiRouter = Router();
|
||||
apiRouter.use('/catalog', await catalog(catalogEnv));
|
||||
@@ -131,6 +148,7 @@ async function main() {
|
||||
apiRouter.use('/graphql', await graphql(graphqlEnv));
|
||||
apiRouter.use('/badges', await badges(badgesEnv));
|
||||
apiRouter.use('/jenkins', await jenkins(jenkinsEnv));
|
||||
apiRouter.use('/permission', await permission(permissionEnv));
|
||||
apiRouter.use(notFoundHandler());
|
||||
|
||||
const service = createServiceBuilder(module)
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { IdentityClient } from '@backstage/plugin-auth-backend';
|
||||
import { createRouter } from '@backstage/plugin-permission-backend';
|
||||
import { AuthorizeResult } from '@backstage/plugin-permission-common';
|
||||
import {
|
||||
PermissionPolicy,
|
||||
PolicyDecision,
|
||||
} from '@backstage/plugin-permission-node';
|
||||
import { Router } from 'express';
|
||||
import { PluginEnvironment } from '../types';
|
||||
|
||||
class AllowAllPermissionPolicy implements PermissionPolicy {
|
||||
async handle(): Promise<PolicyDecision> {
|
||||
return {
|
||||
result: AuthorizeResult.ALLOW,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default async function createPlugin(
|
||||
env: PluginEnvironment,
|
||||
): Promise<Router> {
|
||||
const { logger, discovery } = env;
|
||||
return await createRouter({
|
||||
logger,
|
||||
discovery,
|
||||
policy: new AllowAllPermissionPolicy(),
|
||||
identity: new IdentityClient({
|
||||
discovery,
|
||||
issuer: await discovery.getExternalBaseUrl('auth'),
|
||||
}),
|
||||
});
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
TokenManager,
|
||||
UrlReader,
|
||||
} from '@backstage/backend-common';
|
||||
import { ServerPermissionClient } from '@backstage/plugin-permission-node';
|
||||
|
||||
export type PluginEnvironment = {
|
||||
logger: Logger;
|
||||
@@ -32,4 +33,5 @@ export type PluginEnvironment = {
|
||||
reader: UrlReader;
|
||||
discovery: PluginEndpointDiscovery;
|
||||
tokenManager: TokenManager;
|
||||
permissions: ServerPermissionClient;
|
||||
};
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
"clean": "backstage-cli clean"
|
||||
},
|
||||
"dependencies": {
|
||||
"@backstage/backend-common": "^0.9.11",
|
||||
"@backstage/config": "^0.1.11",
|
||||
"@backstage/plugin-auth-backend": "^0.5.0",
|
||||
"@backstage/plugin-permission-common": "^0.2.0",
|
||||
"@types/express": "^4.17.6",
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2021 The Backstage Authors
|
||||
*
|
||||
* 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 { ServerTokenManager } from '@backstage/backend-common';
|
||||
import { Config } from '@backstage/config';
|
||||
import {
|
||||
AuthorizeRequest,
|
||||
AuthorizeRequestOptions,
|
||||
AuthorizeResponse,
|
||||
AuthorizeResult,
|
||||
DiscoveryApi,
|
||||
PermissionClient,
|
||||
} from '@backstage/plugin-permission-common';
|
||||
|
||||
export class ServerPermissionClient extends PermissionClient {
|
||||
private readonly serverTokenManager: ServerTokenManager;
|
||||
|
||||
constructor(options: {
|
||||
discoveryApi: DiscoveryApi;
|
||||
configApi: Config;
|
||||
serverTokenManager: ServerTokenManager;
|
||||
}) {
|
||||
const { discoveryApi, configApi, serverTokenManager } = options;
|
||||
super({ discoveryApi, configApi });
|
||||
this.serverTokenManager = serverTokenManager;
|
||||
}
|
||||
|
||||
async authorize(
|
||||
requests: AuthorizeRequest[],
|
||||
options?: AuthorizeRequestOptions,
|
||||
): Promise<AuthorizeResponse[]> {
|
||||
if (await this.isValidServerToken(options?.token)) {
|
||||
return requests.map(_ => ({ result: AuthorizeResult.ALLOW }));
|
||||
}
|
||||
return super.authorize(requests, options);
|
||||
}
|
||||
|
||||
private async isValidServerToken(
|
||||
token: string | undefined,
|
||||
): Promise<boolean> {
|
||||
if (!token) {
|
||||
return false;
|
||||
}
|
||||
return this.serverTokenManager
|
||||
.authenticate(token)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
}
|
||||
}
|
||||
@@ -22,3 +22,4 @@
|
||||
export * from './integration';
|
||||
export * from './policy';
|
||||
export * from './types';
|
||||
export { ServerPermissionClient } from './ServerPermissionClient';
|
||||
|
||||
Reference in New Issue
Block a user