Permission FIxes including appId and DataSourceId (#12184)

* init

* remove ForwardAbility
This commit is contained in:
Rudhra Deep Biswas 2025-03-10 17:19:44 +05:30 committed by GitHub
parent e4ffbfe21d
commit ae3142dd4e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 61 additions and 53 deletions

View file

@ -20,8 +20,4 @@ export class AppGitAbilityGuard extends AbilityGuard {
protected getSubjectType() {
return App;
}
protected forwardAbility(): boolean {
return true;
}
}

View file

@ -14,7 +14,13 @@ export class AppGitAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
return App;
}
protected defineAbilityFor(can: AbilityBuilder<AppGitAbility>['can'], UserAllPermissions: UserAllPermissions): void {
protected defineAbilityFor(
can: AbilityBuilder<AppGitAbility>['can'],
UserAllPermissions: UserAllPermissions,
extractedMetadata: { moduleName: string; features: string[] },
request?: any
): void {
const appId = request?.tj_resource_id;
const { superAdmin, isAdmin, userPermission } = UserAllPermissions;
const userAppGitPermissions = userPermission?.APP;
@ -35,11 +41,12 @@ export class AppGitAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
}
// READ-based features
if (isAllAppsViewable || userAppGitPermissions?.viewableAppsId?.length) {
if (
isAllAppsViewable ||
(userAppGitPermissions?.viewableAppsId?.length && appId && userAppGitPermissions?.viewableAppsId?.includes(appId))
) {
can(FEATURE_KEY.GIT_GET_APPS, App);
can(FEATURE_KEY.GIT_GET_APP, App, {
id: { $in: isAllAppsViewable ? undefined : userAppGitPermissions?.viewableAppsId },
});
can(FEATURE_KEY.GIT_GET_APP, App);
}
// CREATE-based features
@ -48,20 +55,21 @@ export class AppGitAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
}
// UPDATE-based features
if (isAllAppsEditable || userAppGitPermissions?.editableAppsId?.length) {
can(FEATURE_KEY.GIT_UPDATE_APP, App, {
id: { $in: isAllAppsEditable ? undefined : userAppGitPermissions?.editableAppsId },
});
can(FEATURE_KEY.GIT_SYNC_APP, App, {
id: { $in: isAllAppsEditable ? undefined : userAppGitPermissions?.editableAppsId },
});
if (
isAllAppsEditable ||
(userAppGitPermissions?.editableAppsId?.length && appId && userAppGitPermissions.editableAppsId.includes(appId))
) {
can(FEATURE_KEY.GIT_UPDATE_APP, App);
can(FEATURE_KEY.GIT_SYNC_APP, App);
}
// Additional checks based on specific actions
if (userAppGitPermissions?.editableAppsId?.length) {
can(FEATURE_KEY.GIT_GET_APP_CONFIG, App, {
id: { $in: userAppGitPermissions.editableAppsId },
});
if (
userAppGitPermissions?.editableAppsId?.length &&
appId &&
userAppGitPermissions.editableAppsId.includes(appId)
) {
can(FEATURE_KEY.GIT_GET_APP_CONFIG, App);
}
}
}

View file

@ -35,7 +35,6 @@ export abstract class AbilityFactory<TActions extends string, TSubject> {
}
: {}),
}));
if (request) {
request.tj_user_permissions = userPermission;
}

View file

@ -83,7 +83,7 @@ export abstract class AbilityGuard implements CanActivate {
user,
{ moduleName: module, features },
resourceArray,
this.forwardAbility() ? request : undefined
request
);
if (this.forwardAbility()) {

View file

@ -15,7 +15,12 @@ export class FeatureAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
return DataSource;
}
protected defineAbilityFor(can: AbilityBuilder<FeatureAbility>['can'], UserAllPermissions: UserAllPermissions): void {
protected defineAbilityFor(
can: AbilityBuilder<FeatureAbility>['can'],
UserAllPermissions: UserAllPermissions,
extractedMetadata: { moduleName: string; features: string[] },
request?: any
): void {
// Data source permissions
// EE - data source create/delete -> full access
// CE - Admin - full access. builder -> use access
@ -27,6 +32,8 @@ export class FeatureAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
const isCanDelete = userPermission.dataSourceDelete;
const isAllViewable = !!resourcePermissions?.isAllUsable;
const dataSourceId = request?.tj_resource_id;
// Oauth end points available to all
can(FEATURE_KEY.GET_OAUTH2_BASE_URL, DataSource);
can(FEATURE_KEY.AUTHORIZE, DataSource);
@ -81,11 +88,14 @@ export class FeatureAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
return;
}
if (resourcePermissions?.configurableDataSourceId?.length) {
if (
resourcePermissions?.configurableDataSourceId?.length &&
dataSourceId &&
resourcePermissions?.configurableDataSourceId?.includes(dataSourceId)
) {
can(
[FEATURE_KEY.GET, FEATURE_KEY.UPDATE, FEATURE_KEY.GET_BY_ENVIRONMENT, FEATURE_KEY.TEST_CONNECTION],
DataSource,
{ id: { $in: resourcePermissions.configurableDataSourceId } }
DataSource
);
}
@ -93,10 +103,12 @@ export class FeatureAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
can([FEATURE_KEY.GET, FEATURE_KEY.GET_BY_ENVIRONMENT], DataSource);
return;
}
if (resourcePermissions.usableDataSourcesId?.length) {
can([FEATURE_KEY.GET, FEATURE_KEY.GET_BY_ENVIRONMENT], DataSource, {
id: { $in: resourcePermissions.usableDataSourcesId },
});
if (
resourcePermissions.usableDataSourcesId?.length &&
dataSourceId &&
resourcePermissions?.usableDataSourcesId?.includes(dataSourceId)
) {
can([FEATURE_KEY.GET, FEATURE_KEY.GET_BY_ENVIRONMENT], DataSource);
}
}
}

View file

@ -15,10 +15,6 @@ export class FeatureAbilityGuard extends AbilityGuard {
return App;
}
protected forwardAbility(): boolean {
return true;
}
protected getResource(): ResourceDetails | ResourceDetails[] {
return [
{

View file

@ -12,8 +12,4 @@ export class FeatureAbilityGuard extends AbilityGuard {
protected getAbilityFactory() {
return FeatureAbilityFactory;
}
protected forwardAbility(): boolean {
return true;
}
}

View file

@ -48,7 +48,7 @@ export const BASIC_PLAN_TERMS: Partial<Terms> = {
export const BASIC_PLAN_SETTINGS = {
ALLOW_PERSONAL_WORKSPACE: {
value: 'true',
value: 'false',
},
WHITE_LABEL_LOGO: {
value: '',

View file

@ -12,8 +12,4 @@ export class FeatureAbilityGuard extends AbilityGuard {
protected getSubjectType() {
return InternalTable;
}
protected forwardAbility(): boolean {
return true;
}
}

View file

@ -15,7 +15,13 @@ export class FeatureAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
return App;
}
protected defineAbilityFor(can: AbilityBuilder<FeatureAbility>['can'], UserAllPermissions: UserAllPermissions): void {
protected defineAbilityFor(
can: AbilityBuilder<FeatureAbility>['can'],
UserAllPermissions: UserAllPermissions,
extractedMetadata: { moduleName: string; features: string[] },
request?: any
): void {
const appId = request?.tj_resource_id;
const { superAdmin, isAdmin, userPermission } = UserAllPermissions;
const userAppPermissions = userPermission?.[MODULES.APP];
@ -52,7 +58,7 @@ export class FeatureAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
return;
}
if (userAppPermissions?.editableAppsId?.length) {
if (userAppPermissions?.editableAppsId?.length && appId && userAppPermissions.editableAppsId.includes(appId)) {
can(
[
FEATURE_KEY.GET,
@ -76,16 +82,19 @@ export class FeatureAbilityFactory extends AbilityFactory<FEATURE_KEY, Subjects>
FEATURE_KEY.UPDATE_EVENT,
FEATURE_KEY.DELETE_EVENT,
],
App,
{ id: { $in: userAppPermissions.editableAppsId } }
App
);
}
if (isAllAppsViewable) {
// add view permissions for all apps
can([FEATURE_KEY.GET_EVENTS], App);
} else if (userAppPermissions?.viewableAppsId?.length) {
can([FEATURE_KEY.GET_EVENTS], App, { id: { $in: userAppPermissions.viewableAppsId } });
} else if (
userAppPermissions?.viewableAppsId?.length &&
appId &&
userAppPermissions.viewableAppsId.includes(appId)
) {
can([FEATURE_KEY.GET_EVENTS], App);
}
}
}

View file

@ -15,10 +15,6 @@ export class FeatureAbilityGuard extends AbilityGuard {
return App;
}
protected forwardAbility(): boolean {
return true;
}
protected getResource(): ResourceDetails | ResourceDetails[] {
return [
{