mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-12 13:27:31 -08:00
refactor: Add telemetry for RBAC (no-changelog) (#8056)
https://linear.app/n8n/issue/PAY-1142
This commit is contained in:
parent
a895ee87fc
commit
38d1336fa7
|
@ -12,4 +12,23 @@ export class RoleRepository extends Repository<Role> {
|
||||||
async findRole(scope: RoleScopes, name: RoleNames) {
|
async findRole(scope: RoleScopes, name: RoleNames) {
|
||||||
return this.findOne({ where: { scope, name } });
|
return this.findOne({ where: { scope, name } });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Counts the number of users in each role, e.g. `{ admin: 2, member: 6, owner: 1 }`
|
||||||
|
*/
|
||||||
|
async countUsersByRole() {
|
||||||
|
type Row = { role_name: string; count: number };
|
||||||
|
|
||||||
|
const rows: Row[] = await this.createQueryBuilder('role')
|
||||||
|
.select('role.name')
|
||||||
|
.addSelect('COUNT(user.id)', 'count')
|
||||||
|
.innerJoin('user', 'user', 'role.id = user.globalRoleId')
|
||||||
|
.groupBy('role.name')
|
||||||
|
.getRawMany();
|
||||||
|
|
||||||
|
return rows.reduce<Record<string, number>>((acc, item) => {
|
||||||
|
acc[item.role_name] = item.count;
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import { License } from '@/License';
|
||||||
import { N8N_VERSION } from '@/constants';
|
import { N8N_VERSION } from '@/constants';
|
||||||
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
import { WorkflowRepository } from '@db/repositories/workflow.repository';
|
||||||
import { SourceControlPreferencesService } from '../environments/sourceControl/sourceControlPreferences.service.ee';
|
import { SourceControlPreferencesService } from '../environments/sourceControl/sourceControlPreferences.service.ee';
|
||||||
|
import { RoleRepository } from '@/databases/repositories/role.repository';
|
||||||
|
|
||||||
type ExecutionTrackDataKey = 'manual_error' | 'manual_success' | 'prod_error' | 'prod_success';
|
type ExecutionTrackDataKey = 'manual_error' | 'manual_success' | 'prod_error' | 'prod_success';
|
||||||
|
|
||||||
|
@ -110,6 +111,7 @@ export class Telemetry {
|
||||||
plan_name_current: this.license.getPlanName(),
|
plan_name_current: this.license.getPlanName(),
|
||||||
quota: this.license.getTriggerLimit(),
|
quota: this.license.getTriggerLimit(),
|
||||||
usage: await this.workflowRepository.getActiveTriggerCount(),
|
usage: await this.workflowRepository.getActiveTriggerCount(),
|
||||||
|
role_count: await Container.get(RoleRepository).countUsersByRole(),
|
||||||
source_control_set_up: Container.get(SourceControlPreferencesService).isSourceControlSetup(),
|
source_control_set_up: Container.get(SourceControlPreferencesService).isSourceControlSetup(),
|
||||||
branchName: sourceControlPreferences.branchName,
|
branchName: sourceControlPreferences.branchName,
|
||||||
read_only_instance: sourceControlPreferences.branchReadOnly,
|
read_only_instance: sourceControlPreferences.branchReadOnly,
|
||||||
|
|
37
packages/cli/test/integration/role.repository.test.ts
Normal file
37
packages/cli/test/integration/role.repository.test.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
import { createAdmin, createMember, createOwner } from './shared/db/users';
|
||||||
|
import * as testDb from './shared/testDb';
|
||||||
|
import { RoleRepository } from '@/databases/repositories/role.repository';
|
||||||
|
import Container from 'typedi';
|
||||||
|
|
||||||
|
describe('RoleRepository', () => {
|
||||||
|
let roleRepository: RoleRepository;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await testDb.init();
|
||||||
|
|
||||||
|
roleRepository = Container.get(RoleRepository);
|
||||||
|
|
||||||
|
await testDb.truncate(['User']);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await testDb.terminate();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('countUsersByRole()', () => {
|
||||||
|
test('should return the number of users in each role', async () => {
|
||||||
|
await Promise.all([
|
||||||
|
createOwner(),
|
||||||
|
createAdmin(),
|
||||||
|
createAdmin(),
|
||||||
|
createMember(),
|
||||||
|
createMember(),
|
||||||
|
createMember(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const usersByRole = await roleRepository.countUsersByRole();
|
||||||
|
|
||||||
|
expect(usersByRole).toStrictEqual({ admin: 2, member: 3, owner: 1 });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1772,6 +1772,7 @@ export interface ExternalSecretsProviderWithProperties extends ExternalSecretsPr
|
||||||
}
|
}
|
||||||
|
|
||||||
export type CloudUpdateLinkSourceType =
|
export type CloudUpdateLinkSourceType =
|
||||||
|
| 'advanced-permissions'
|
||||||
| 'canvas-nav'
|
| 'canvas-nav'
|
||||||
| 'custom-data-filter'
|
| 'custom-data-filter'
|
||||||
| 'workflow_sharing'
|
| 'workflow_sharing'
|
||||||
|
|
|
@ -333,7 +333,7 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
goToUpgradeAdvancedPermissions() {
|
goToUpgradeAdvancedPermissions() {
|
||||||
void this.uiStore.goToUpgrade('settings-users', 'upgrade-advanced-permissions');
|
void this.uiStore.goToUpgrade('advanced-permissions', 'upgrade-advanced-permissions');
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue