Skip to content

Commit

Permalink
fix(rbac): prevent policy creation when rbac plugin is disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
PatAKnight committed Oct 21, 2024
1 parent 7a28963 commit 67e48b9
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 15 deletions.
67 changes: 67 additions & 0 deletions plugins/rbac-backend/src/policies/allow-all-policy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {
AuthorizeResult,
createPermission,
} from '@backstage/plugin-permission-common';
import {
PermissionPolicy,
PolicyQuery,
PolicyQueryUser,
} from '@backstage/plugin-permission-node';

import { AllowAllPolicy } from './allow-all-policy';

describe('Allow All Policy', () => {
describe('Allow all policy should allow all', () => {
let policy: PermissionPolicy;
beforeEach(() => {
policy = new AllowAllPolicy();
});

it('should be able to create an allow all permission policy', () => {
expect(policy).not.toBeNull();
});

it('should allow all when handle is called', async () => {
const result = await policy.handle(
newPolicyQueryWithBasicPermission('catalog.entity.create'),
newPolicyQueryUser('user:default/guest'),
);

expect(result).toStrictEqual({ result: AuthorizeResult.ALLOW });
});
});
});

function newPolicyQueryWithBasicPermission(name: string): PolicyQuery {
const mockPermission = createPermission({
name: name,
attributes: {},
});
return { permission: mockPermission };
}

function newPolicyQueryUser(
user?: string,
ownershipEntityRefs?: string[],
): PolicyQueryUser | undefined {
if (user) {
return {
identity: {
ownershipEntityRefs: ownershipEntityRefs ?? [],
type: 'user',
userEntityRef: user,
},
credentials: {
$$type: '@backstage/BackstageCredentials',
principal: true,
expiresAt: new Date('2021-01-01T00:00:00Z'),
},
info: {
userEntityRef: user,
ownershipEntityRefs: ownershipEntityRefs ?? [],
},
token: 'token',
};
}
return undefined;
}
18 changes: 18 additions & 0 deletions plugins/rbac-backend/src/policies/allow-all-policy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {
AuthorizeResult,
PolicyDecision,
} from '@backstage/plugin-permission-common';
import {
PermissionPolicy,
PolicyQuery,
PolicyQueryUser,
} from '@backstage/plugin-permission-node';

export class AllowAllPolicy implements PermissionPolicy {
async handle(
_request: PolicyQuery,
_user?: PolicyQueryUser,
): Promise<PolicyDecision> {
return { result: AuthorizeResult.ALLOW };
}
}
2 changes: 1 addition & 1 deletion plugins/rbac-backend/src/service/policy-builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ describe('PolicyBuilder', () => {
expect(CasbinDBAdapterFactory).toHaveBeenCalled();
expect(mockEnforcer.loadPolicy).toHaveBeenCalled();
expect(mockEnforcer.enableAutoSave).toHaveBeenCalled();
expect(RBACPermissionPolicy.build).toHaveBeenCalled();
expect(RBACPermissionPolicy.build).not.toHaveBeenCalled();

expect(PoliciesServer).toHaveBeenCalled();
expect(mockPoliciesServer.serve).toHaveBeenCalled();
Expand Down
36 changes: 22 additions & 14 deletions plugins/rbac-backend/src/service/policy-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { CatalogClient } from '@backstage/catalog-client';
import type { Config } from '@backstage/config';
import type { RouterOptions } from '@backstage/plugin-permission-backend';
import type { PermissionEvaluator } from '@backstage/plugin-permission-common';
import { PermissionPolicy } from '@backstage/plugin-permission-node';

import { newEnforcer, newModelFromString } from 'casbin';
import type { Router } from 'express';
Expand All @@ -25,6 +26,7 @@ import { CasbinDBAdapterFactory } from '../database/casbin-adapter-factory';
import { DataBaseConditionalStorage } from '../database/conditional-storage';
import { migrate } from '../database/migration';
import { DataBaseRoleMetadataStorage } from '../database/role-metadata';
import { AllowAllPolicy } from '../policies/allow-all-policy';
import { connectRBACProviders } from '../providers/connect-providers';
import { BackstageRoleManager } from '../role-manager/role-manager';
import { EnforcerDelegate } from './enforcer-delegate';
Expand All @@ -48,14 +50,7 @@ export class PolicyBuilder {
pluginIdProvider: PluginIdProvider = { getPluginIds: () => [] },
rbacProviders?: Array<RBACProvider>,
): Promise<Router> {
const isPluginEnabled = env.config.getOptionalBoolean('permission.enabled');
if (isPluginEnabled) {
env.logger.info('RBAC backend plugin was enabled');
} else {
env.logger.warn(
'RBAC backend plugin was disabled by application config permission.enabled: false',
);
}
let policy: PermissionPolicy;

const databaseManager = DatabaseManager.fromConfig(env.config).forPlugin(
'permission',
Expand Down Expand Up @@ -139,11 +134,11 @@ export class PolicyBuilder {
},
});

const options: RouterOptions = {
config: env.config,
logger: env.logger,
discovery: env.discovery,
policy: await RBACPermissionPolicy.build(
const isPluginEnabled = env.config.getOptionalBoolean('permission.enabled');
if (isPluginEnabled) {
env.logger.info('RBAC backend plugin was enabled');

policy = await RBACPermissionPolicy.build(
env.logger,
defAuditLog,
env.config,
Expand All @@ -153,7 +148,20 @@ export class PolicyBuilder {
databaseClient,
pluginPermMetaData,
env.auth,
),
);
} else {
env.logger.warn(
'RBAC backend plugin was disabled by application config permission.enabled: false',
);

policy = new AllowAllPolicy();
}

const options: RouterOptions = {
config: env.config,
logger: env.logger,
discovery: env.discovery,
policy,
auth: env.auth,
httpAuth: env.httpAuth,
userInfo: env.userInfo,
Expand Down

0 comments on commit 67e48b9

Please sign in to comment.