Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

User group revamp #9534

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/src/_services/authentication.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ function signInViaOAuth(configId, ssoType, ssoResponse) {
});
}

//TODO:remove this function if its not used
function authorize() {
const requestOptions = {
method: 'GET',
Expand Down
38 changes: 38 additions & 0 deletions server/migrations/1714015513342-AddGroupPermissionsTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { MigrationInterface, QueryRunner } from 'typeorm';
import { DATA_BASE_CONSTRAINTS } from '@module/user_resource_permissions/constants/group-permissions.constant';

export class AddGroupPermissionsTable1714015513342 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`
CREATE TYPE group_permissions_type AS ENUM ('custom', 'default');
`
);

//Remove data source level permissions in CE
await queryRunner.query(`
CREATE TABLE IF NOT EXISTS group_permissions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID,
name VARCHAR NOT NULL,
type group_permissions_type NOT NULL DEFAULT 'custom',
app_create BOOLEAN DEFAULT false,
app_delete BOOLEAN DEFAULT false,
folder_crud BOOLEAN DEFAULT false,
org_constant_crud BOOLEAN DEFAULT false,
org_variable_crud BOOLEAN DEFAULT false,
data_source_create BOOLEAN DEFAULT false,
data_source_delete BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_organization_id FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE,
CONSTRAINT ${DATA_BASE_CONSTRAINTS.GROUP_NAME_UNIQUE.dbConstraint} UNIQUE (organization_id, name)
);
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE IF EXISTS group_permissions`);
await queryRunner.query(`DROP TYPE IF EXISTS group_permissions_type;`);
}
}
25 changes: 25 additions & 0 deletions server/migrations/1714015541245-AddGroupUsersTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { DATA_BASE_CONSTRAINTS } from '@module/user_resource_permissions/constants/group-permissions.constant';
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddGroupUsersTable1714015541245 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`
CREATE TABLE IF NOT EXISTS group_users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID,
group_id UUID,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
CONSTRAINT fk_group_id FOREIGN KEY (group_id) REFERENCES group_permissions(id) ON DELETE CASCADE,
CONSTRAINT ${DATA_BASE_CONSTRAINTS.GROUP_USER_UNIQUE.dbConstraint} UNIQUE (user_id, group_id)
);
`
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE IF EXISTS group_users`);
}
}
32 changes: 32 additions & 0 deletions server/migrations/1714015564318-AddGranularPermissionsTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { DATA_BASE_CONSTRAINTS } from '@module/user_resource_permissions/constants/group-permissions.constant';
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddGranularPermissionsTable1714015564318 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`
CREATE TYPE resource_type AS ENUM ('app', 'data_source');
`
);

await queryRunner.query(
`
CREATE TABLE granular_permissions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
group_id UUID,
name VARCHAR NOT NULL,
type resource_type NOT NULL,
is_all BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_group_id FOREIGN KEY (group_id) REFERENCES group_permissions(id) ON DELETE CASCADE,
CONSTRAINT ${DATA_BASE_CONSTRAINTS.GRANULAR_PERMISSIONS_NAME_UNIQUE.dbConstraint} UNIQUE (name, group_id)
);
`
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE IF EXISTS granular_permissions`);
}
}
28 changes: 28 additions & 0 deletions server/migrations/1714015596201-AddAppsGroupPermissionsTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddAppsGroupPermissionsTable1714015596201 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`
CREATE TABLE IF NOT EXISTS apps_group_permissions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
granular_permission_id UUID,
can_edit BOOLEAN DEFAULT false,
can_view BOOLEAN DEFAULT false,
hide_from_dashboard BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_granular_permission_id FOREIGN KEY (granular_permission_id) REFERENCES granular_permissions(id) ON DELETE CASCADE
);
`
);

await queryRunner.query(
`CREATE INDEX idx_granular_permission_id ON apps_group_permissions(granular_permission_id);`
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE IF EXISTS apps_group_permissions`);
}
}
23 changes: 23 additions & 0 deletions server/migrations/1714015615904-AddGroupAppsTable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class AddGroupAppsTable1714015615904 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`
CREATE TABLE IF NOT EXISTS group_apps (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
app_id UUID,
apps_group_permissions_id UUID,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT fk_app_id FOREIGN KEY (app_id) REFERENCES apps(id) ON DELETE CASCADE,
CONSTRAINT fk_apps_group_permissions_id FOREIGN KEY (apps_group_permissions_id) REFERENCES apps_group_permissions(id) ON DELETE CASCADE
);
`
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`DROP TABLE IF EXISTS group_apps`);
}
}
3 changes: 3 additions & 0 deletions server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import { ScheduleModule } from '@nestjs/schedule';
import { ImportExportResourcesModule } from './modules/import_export_resources/import_export_resources.module';
import { MailerModule } from '@nestjs-modules/mailer';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { UserResourcePermissionsModule } from '@module/user_resource_permissions/user_resource_permissions.module';

const imports = [
ScheduleModule.forRoot(),
Expand Down Expand Up @@ -130,7 +131,9 @@ const imports = [
CaslModule,
MetaModule,
LibraryAppModule,
//Need to add new module
GroupPermissionsModule,
UserResourcePermissionsModule,
FilesModule,
PluginsModule,
EventsModule,
Expand Down
64 changes: 64 additions & 0 deletions server/src/constants/global.constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
export enum TOOLJET_RESOURCE {
APP = 'App',
ORGANIZATIONS = 'Organization',
USER = 'User',
PLUGINS = 'Plugins',
GLOBAL_DATA_SOURCE = 'GlobalDataSource',
DATA_QUERY = 'DataQueries',
THREAD = 'Thread',
COMMENT = 'Comment',
FOLDER = 'Folder',
ORGANIZATION_VARIABLE = 'OrgEnvironmentVariable',
ORGANIZATION_CONSTANT = 'OrganizationConstant',
}

export enum APP_RESOURCE_ACTIONS {
CREATE = 'create',
UPDATE = 'update',
DELETE = 'delete',
READ = 'read',
CLONE = 'clone',
IMPORT = 'import',
VIEW = 'view',
EDIT = 'edit',
VERSIONS_CREATE = 'createVersions',
VERSION_UPDATE = 'deleteVersions',
VERSION_DELETE = 'updateVersions',
VERSION_READ = 'read脽Versions',
}
export enum GLOBAL_DATA_SOURCE_RESOURCE_ACTIONS {}
export enum LOCAL_DATA_SOURCE_RESOURCE_ACTIONS {
CREATE = 'create',
DELETE = 'delete',
READ = 'read',
UPDATE = 'update',
}
export enum DATA_QUERIES_RESOURCE_ACTIONS {
CREATE = 'create',
DELETE = 'delete',
READ = 'read',
UPDATE = 'update',
RUN = 'run',
}
export enum ORGANIZATION_CONSTANT_RESOURCE_ACTIONS {
CREATE = 'create',
UPDATE = 'update',
DELETE = 'delete',
}
export enum ORGANIZATION_VARIABLE_ACTIONS {
CREATE = 'create',
UPDATE = 'update',
DELETE = 'delete',
}
export enum USER_RESOURCE_ACTIONS {
CREATE = 'create',
UPDATE = 'update',
DELETE = 'delete',
READ = 'read',
}
export enum ORGANIZATION_RESOURCE_ACTIONS {}
export enum FOLDER_RESOURCE_ACTION {
CREATE = 'create',
UPDATE = 'update',
DELETE = 'delete',
}
1 change: 1 addition & 0 deletions server/src/controllers/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export class AppController {

let app: { organizationId: string; isPublic: boolean };
if (appId) {
//TODO: This function should not be part pf userService
app = await this.userService.returnOrgIdOfAnApp(appId);
}

Expand Down
1 change: 1 addition & 0 deletions server/src/controllers/app_users.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class AppUsersController {
const app = await this.appsService.find(appId);
const ability = await this.appsAbilityFactory.appsActions(req.user, appId);

//This ability should be transfers to other ability
if (!ability.can('createUsers', app)) {
throw new ForbiddenException('you do not have permissions to perform this action');
}
Expand Down