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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix] Correct project manager permission validation logic #8794

Open
wants to merge 15 commits into
base: develop
Choose a base branch
from

Conversation

samuelmbabhazi
Copy link
Contributor

@samuelmbabhazi samuelmbabhazi commented Feb 19, 2025

PR

Please note: we will close your PR without comment if you do not check the boxes above and provide ALL requested information.


Summary by CodeRabbit

  • New Features

    • Improved Project Permissions: Project selection now features dynamic permission checks, ensuring that user roles and access are accurately verified when managing projects.
    • Streamlined Team Management: Team creation and editing have been enhanced by automatically assigning eligible users as managers, simplifying the process and improving overall team configuration.
    • Access Control Enhancements: New guards have been implemented to manage access to project-related routes based on user permissions and managerial status.
    • Manager Verification: A new method allows for checking if a specified employee is a manager of a project, enhancing permission validation.
    • Enhanced Error Handling: Improved error handling logic for integration processes, providing specific responses to different error conditions.
  • Bug Fixes

    • Resolved issues related to user permissions not accurately reflecting in project management actions.

@samuelmbabhazi samuelmbabhazi self-assigned this Feb 19, 2025
Copy link
Contributor

coderabbitai bot commented Feb 19, 2025

Walkthrough

This pull request introduces several enhancements across multiple Angular components and services. In the ProjectListComponent, two methods—isManagerOfProject and hasAllPermissions—are added, and the constructor is modified to include NgxPermissionsService. The selectProject method is updated to dynamically adjust the CAN_MANAGE_PROJECT permission. The TeamsMutationComponent gains a new method, initializeManager(), which automatically assigns the current user as a manager during initialization. Additionally, two new guards are introduced to manage route access based on user permissions, along with several new methods to check managerial status across different services.

Changes

File(s) Change Summary
apps/gauzy/.../project-list/list.component.ts Added isManagerOfProject and hasAllPermissions methods; updated constructor to include NgxPermissionsService; modified selectProject to adjust CAN_MANAGE_PROJECT permission; refined member filtering.
apps/gauzy/.../teams-mutation/teams-mutation.component.ts Added initializeManager() method to auto-assign the current employee as manager during ngOnInit, patching the form with the employee ID and updating form control validity.
apps/gauzy/.../guards/project-manager-permission.guard.ts Introduced ProjectManagerPermissionGuard class with canActivate method to control route access based on user permissions.
apps/gauzy/.../guards/project-manager.guard.ts Introduced ProjectManagerGuard class with canActivate method to manage access based on user permissions and managerial status for projects.
packages/core/.../organization-project.controller.ts Added isManager method to check if an employee is a manager of a project via a GET endpoint.
packages/core/.../organization-project.service.ts Added isManagerOfProject method to verify if an employee is a manager of a project using TypeORM.
packages/ui-core/.../organization-projects.service.ts Added isManagerOfProject method to check if an employee is a manager of a project via a GET request.
apps/gauzy/.../projects/projects-routing.module.ts Updated routing to use ProjectManagerPermissionGuard instead of PermissionsGuard for project editing routes.

Possibly related PRs

Suggested reviewers

  • rahul-rocket

Poem

I’m a coding rabbit, hopping with delight,
In project lists and teams, I’ve made things right.
Permissions check and managers set with care,
Form and logic dancing in the open air.
A hop, a skip, and lines of code so neat—
Celebrating this PR, where all things meet!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 06b26dd and 725560f.

📒 Files selected for processing (1)
  • apps/gauzy/src/app/pages/projects/guards/project-manager-permission.guard.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/gauzy/src/app/pages/projects/guards/project-manager-permission.guard.ts
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: test
  • GitHub Check: build
  • GitHub Check: Codacy Static Code Analysis

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@samuelmbabhazi samuelmbabhazi marked this pull request as ready for review February 19, 2025 17:11
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/gauzy/src/app/pages/teams/teams-mutation/teams-mutation.component.ts (1)

75-86: LGTM! Consider adding error handling.

The implementation of initializeManager() is clean and well-documented. It effectively sets the current user as a manager when they are an employee.

Consider adding error handling for the form operations:

 initializeManager() {
   const { employee } = this.store.user;
   if (employee) {
+    try {
       this.form.patchValue({
         managerIds: [employee.id]
       });
       this.form.get('managerIds').updateValueAndValidity();
+    } catch (error) {
+      console.error('Error initializing manager:', error);
+    }
   }
 }
apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (1)

547-564: Consider adding error handling for permission operations.

The permission management in selectProject is well-structured but could benefit from error handling around permission operations.

Consider wrapping the permission operations in a try-catch block:

 if (isSelected && this.selectedProject) {
   const isManager = this.isManagerOfProject(this.selectedProject);
   const hasAllPermissions = this.hasAllPermissions([
     PermissionsEnum.ALL_ORG_EDIT,
     PermissionsEnum.ORG_PROJECT_EDIT,
     PermissionsEnum.ORG_PROJECT_DELETE
   ]);

+  try {
     if (isManager || hasAllPermissions) {
       this._permissionsService.addPermission('CAN_MANAGE_PROJECT');
     } else {
       this._permissionsService.removePermission('CAN_MANAGE_PROJECT');
     }
+  } catch (error) {
+    console.error('Error managing project permissions:', error);
+  }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ab4a297 and 4879211.

📒 Files selected for processing (3)
  • apps/gauzy/src/app/pages/projects/components/project-list/list.component.html (3 hunks)
  • apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (5 hunks)
  • apps/gauzy/src/app/pages/teams/teams-mutation/teams-mutation.component.ts (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: test
  • GitHub Check: build
🔇 Additional comments (3)
apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (2)

284-286: LGTM! The manager check is accurate and efficient.

The isManagerOfProject method correctly verifies if the current user is a manager of the project by checking their user ID against the project's manager list.


614-616: LGTM! The permission check is well-implemented.

The hasAllPermissions method efficiently verifies multiple permissions using every to ensure all required permissions are present.

apps/gauzy/src/app/pages/projects/components/project-list/list.component.html (1)

67-108: LGTM! Permission checks are well-consolidated.

The template changes effectively simplify permission management by:

  • Reducing duplication in permission checks
  • Using a single, consistent 'CAN_MANAGE_PROJECT' permission
  • Improving template readability

Copy link

nx-cloud bot commented Feb 19, 2025

View your CI Pipeline Execution ↗ for commit 725560f.

Command Status Duration Result
nx build desktop --base-href ./ ✅ Succeeded 1m 49s View ↗
nx build desktop-api --output-path=dist/apps/de... ✅ Succeeded 28s View ↗
nx run api:desktop-api ✅ Succeeded 1m 18s View ↗
nx run gauzy:desktop-ui --base-href ./ ✅ Succeeded 3m 33s View ↗
nx build gauzy -c=production --prod --verbose ✅ Succeeded 3m 40s View ↗
nx build desktop-ui-lib --configuration=production ✅ Succeeded 30s View ↗
nx build plugin-integration-wakatime ✅ Succeeded <1s View ↗
nx build desktop-lib ✅ Succeeded <1s View ↗
Additional runs (56) ✅ Succeeded ... View ↗

☁️ Nx Cloud last updated this comment at 2025-02-24 17:22:21 UTC

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (1)

253-253: Remove debug console.log statement.

Remove the console.log statement as it's not needed in production code.

-				console.log(project);
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4879211 and 8025ad6.

📒 Files selected for processing (1)
  • apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (7 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: test
🔇 Additional comments (3)
apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (3)

285-287: LGTM! Well-structured method for checking project manager status.

The method efficiently checks if the current user is a manager of the project by comparing the user ID with the project member's employee user ID.


365-365: LGTM! Improved property access path.

The change correctly accesses the employee ID through the user's employee property.


619-621: LGTM! Clean implementation of permission check.

The method efficiently checks if the user has all the required permissions using Array.every().

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (6)
apps/gauzy/src/app/pages/projects/guards/project-manager-permission.guard.ts (1)

36-46: Consider enhancing error handling in the permissions check flow.

While the current implementation handles the basic flow well, consider adding error handling for the permissions guard check similar to what's done for the manager guard.

 this._permissionsGuard.canActivate(route, state).subscribe(
   (hasPermissions) => {
     if (hasPermissions) {
       observer.next(true);
     } else {
       this._router.navigate([route.data['permissions'].redirectTo || '/pages/dashboard']);
       observer.next(false);
     }
     observer.complete();
+  },
+  (error) => {
+    console.error('Error checking permissions:', error);
+    this._router.navigate(['/pages/dashboard']);
+    observer.next(false);
+    observer.complete();
   }
 );
apps/gauzy/src/app/pages/projects/guards/project-manager.guard.ts (1)

29-35: Enhance type safety in permission check condition.

The current implementation might be prone to type-related issues. Consider using explicit type checks.

-if (
-  !this._store.user?.employee &&
-  this._store.hasAllPermissions(PermissionsEnum.ORG_PROJECT_EDIT, PermissionsEnum.ORG_PROJECT_DELETE)
-) {
+if (
+  this._store.user !== null &&
+  !this._store.user.employee &&
+  this._store.hasAllPermissions(PermissionsEnum.ORG_PROJECT_EDIT, PermissionsEnum.ORG_PROJECT_DELETE)
+) {
packages/ui-core/core/src/lib/services/organization/organization-projects.service.ts (1)

46-48: Consider adding error handling guidance for consumers.

While the implementation is clean, consider adding error handling documentation for service consumers.

 isManagerOfProject(projectId: ID, employeeId: ID): Observable<boolean> {
-  return this._http.get<boolean>(`${this.API_URL}/${projectId}/is-manager/${employeeId}`);
+  return this._http.get<boolean>(`${this.API_URL}/${projectId}/is-manager/${employeeId}`).pipe(
+    catchError((error) => {
+      console.error('Error checking project manager status:', error);
+      return of(false);
+    })
+  );
 }
packages/core/src/lib/organization-project/organization-project.controller.ts (1)

279-297: Consider enhancing method name and error handling.

The method implementation is good, but could be improved in a few areas:

  1. The method name isManager could be more descriptive, e.g., isEmployeeProjectManager.
  2. The API operation summary could include more details about the parameters.
  3. Consider adding error handling for cases where the project or employee doesn't exist.
-	@ApiOperation({
-		summary: 'Check if an employee is a manager of a specific project.'
-	})
+	@ApiOperation({
+		summary: 'Check if an employee is a manager of a specific project.',
+		description: 'Verifies whether the specified employee (by employeeId) has manager privileges for the given project (by projectId).'
+	})
-	async isManager(
+	async isEmployeeProjectManager(
 		@Param('projectId', UUIDValidationPipe) projectId: ID,
 		@Param('employeeId', UUIDValidationPipe) employeeId: ID
 	): Promise<boolean> {
+		// Verify that both project and employee exist
+		const [project, employee] = await Promise.all([
+			this.organizationProjectService.findOneByIdString(projectId),
+			this.employeeService.findOneByIdString(employeeId)
+		]);
+
+		if (!project || !employee) {
+			throw new NotFoundException('Project or employee not found');
+		}
+
 		return await this.organizationProjectService.isManagerOfProject(projectId, employeeId);
 	}
apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (1)

548-569: Consider caching permission check results.

The permission checks in the selectProject method are well-structured but could be optimized by caching the results to avoid repeated checks.

+	private cachedPermissions = new Map<string, boolean>();
+
+	private getCachedPermissionResult(key: string, checkFn: () => boolean): boolean {
+		if (!this.cachedPermissions.has(key)) {
+			this.cachedPermissions.set(key, checkFn());
+		}
+		return this.cachedPermissions.get(key);
+	}
+
 	async selectProject({ isSelected, data }): Promise<void> {
 		try {
 			this.disableButton = !isSelected;
 			this.selectedProject = isSelected ? data : null;
 
 			if (isSelected && this.selectedProject) {
-				const isManager = this.isManagerOfProject(this.selectedProject);
+				const isManager = this.getCachedPermissionResult(
+					`manager_${this.selectedProject.id}`,
+					() => this.isManagerOfProject(this.selectedProject)
+				);
 
-				const hasAllPermissions = this.hasAllPermissions([
-					PermissionsEnum.ALL_ORG_EDIT,
-					PermissionsEnum.ORG_PROJECT_EDIT,
-					PermissionsEnum.ORG_PROJECT_DELETE
-				]);
+				const hasAllPermissions = this.getCachedPermissionResult(
+					'all_permissions',
+					() => this.hasAllPermissions([
+						PermissionsEnum.ALL_ORG_EDIT,
+						PermissionsEnum.ORG_PROJECT_EDIT,
+						PermissionsEnum.ORG_PROJECT_DELETE
+					])
+				);
packages/core/src/lib/organization-project/organization-project.service.ts (1)

656-673: Consider enhancing error handling and query optimization.

The isManagerOfProject method is well-implemented but could benefit from:

  1. Error handling for database query failures.
  2. Query optimization by selecting only necessary columns.
 	async isManagerOfProject(projectId: ID, employeeId: ID): Promise<boolean> {
+		try {
 			const project = await this.typeOrmRepository
 				.createQueryBuilder('project')
+				.select('project.id')
 				.innerJoin('project.members', 'members')
 				.where('project.id = :projectId', { projectId })
 				.andWhere('members.employeeId = :employeeId', { employeeId })
 				.andWhere('members.isManager = true')
 				.getOne();
 
 			return !!project;
+		} catch (error) {
+			console.error('Error checking project manager status:', error);
+			throw new HttpException(
+				'Failed to check project manager status',
+				HttpStatus.INTERNAL_SERVER_ERROR
+			);
+		}
 	}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8025ad6 and 56346d7.

📒 Files selected for processing (7)
  • apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (7 hunks)
  • apps/gauzy/src/app/pages/projects/guards/project-manager-permission.guard.ts (1 hunks)
  • apps/gauzy/src/app/pages/projects/guards/project-manager.guard.ts (1 hunks)
  • apps/gauzy/src/app/pages/projects/projects-routing.module.ts (2 hunks)
  • packages/core/src/lib/organization-project/organization-project.controller.ts (1 hunks)
  • packages/core/src/lib/organization-project/organization-project.service.ts (1 hunks)
  • packages/ui-core/core/src/lib/services/organization/organization-projects.service.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: test
  • GitHub Check: build
🔇 Additional comments (5)
apps/gauzy/src/app/pages/projects/guards/project-manager-permission.guard.ts (1)

27-50: LGTM! Well-structured permission validation flow.

The guard effectively implements a hierarchical permission check, first verifying project manager status before falling back to general permissions.

apps/gauzy/src/app/pages/projects/guards/project-manager.guard.ts (1)

46-61: LGTM! Well-implemented permission validation with proper error handling.

The guard effectively uses RxJS operators for handling the async flow and error cases.

apps/gauzy/src/app/pages/projects/projects-routing.module.ts (1)

65-70: LGTM! Appropriate guard replacement with maintained permission requirements.

The routing configuration correctly implements the new ProjectManagerPermissionGuard while maintaining the existing permission requirements.

apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (2)

285-287: LGTM! Well-structured method for checking project manager status.

The isManagerOfProject method is well-implemented, using a clean and efficient approach to check if the current user is a manager of the project.


619-621: LGTM! Efficient permission check implementation.

The hasAllPermissions method is well-implemented, using the every array method for efficient permission checking.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
packages/core/src/lib/organization-project/organization-project.module.ts (1)

15-31: Consider documenting the guard's purpose and usage.

To improve maintainability, consider adding a comment block above the @Module decorator explaining:

  • The purpose of the PermissionGuard
  • How it interacts with other guards (ManagerOrPermissionGuard, ProjectManagerPermissionGuard)
  • The permission validation strategy
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56346d7 and b89fc73.

📒 Files selected for processing (5)
  • packages/core/src/lib/organization-project/decorators/manager-or-permission.decorator.ts (1 hunks)
  • packages/core/src/lib/organization-project/guards/manager-or-permission.guard.ts (1 hunks)
  • packages/core/src/lib/organization-project/organization-project.controller.ts (2 hunks)
  • packages/core/src/lib/organization-project/organization-project.module.ts (2 hunks)
  • packages/core/src/lib/organization-project/organization-project.service.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/lib/organization-project/organization-project.service.ts
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: test
🔇 Additional comments (5)
packages/core/src/lib/organization-project/organization-project.module.ts (1)

15-15: LGTM! Addition of PermissionGuard enhances access control.

The integration of PermissionGuard aligns well with the PR's objective of fixing project manager permission validation logic.

Also applies to: 31-31

packages/core/src/lib/organization-project/decorators/manager-or-permission.decorator.ts (1)

1-7: LGTM! Well-structured decorator implementation.

The decorator follows NestJS best practices by combining permission metadata and guard functionality using applyDecorators. The implementation is concise and follows the single responsibility principle.

packages/core/src/lib/organization-project/guards/manager-or-permission.guard.ts (1)

15-37: LGTM! Well-structured guard implementation.

The guard follows NestJS best practices:

  • Properly implements the CanActivate interface
  • Includes informative logging
  • Has a clear fallback mechanism to the permission guard
  • Handles edge cases when employeeId or projectId are missing
packages/core/src/lib/organization-project/organization-project.controller.ts (2)

45-49: LGTM! Good replacement of permission guard.

The switch to ManagerOrPermissionGuard while maintaining TenantPermissionGuard provides better access control by checking both project manager status and permissions.


281-299: LGTM! Well-implemented endpoint for checking manager status.

The new endpoint is:

  • Well-documented with OpenAPI decorators
  • Uses proper validation for UUID parameters
  • Has clear and focused implementation

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/ui-core/core/src/lib/resolvers/integration.resolver.ts (1)

44-51: Enhance error logging for better debugging.

While the error handling is improved, consider adding more context to the error messages:

-				console.warn('Access to integration is forbidden (403), continuing without integration data.');
+				console.warn(`Access to integration "${name}" is forbidden (403). User: ${_store.user?.id}. Continuing without integration data.`);
-				console.error('Unexpected error in IntegrationResolver:', error);
+				console.error('Unexpected error in IntegrationResolver:', { 
+					error, 
+					integration: name, 
+					organizationId, 
+					tenantId 
+				});
apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (1)

547-568: Add error handling for permission operations.

The dynamic permission management logic should include error handling for permission operations.

 if (!hasAllPermissions) {
   const permissions = [PermissionsEnum.ORG_PROJECT_EDIT, PermissionsEnum.ORG_PROJECT_DELETE];

-  permissions.forEach((permission) =>
-    isManager
-      ? this._permissionsService.addPermission(permission)
-      : this._permissionsService.removePermission(permission)
-  );
+  try {
+    await Promise.all(permissions.map(async (permission) => {
+      if (isManager) {
+        await this._permissionsService.addPermission(permission);
+      } else {
+        await this._permissionsService.removePermission(permission);
+      }
+    }));
+  } catch (error) {
+    console.error('Error updating permissions:', error);
+    this._errorHandlingService.handleError(error);
+  }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b89fc73 and 0b72754.

📒 Files selected for processing (6)
  • apps/gauzy/src/app/pages/projects/components/project-edit/edit.component.ts (1 hunks)
  • apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (6 hunks)
  • apps/gauzy/src/app/pages/projects/guards/project-manager.guard.ts (1 hunks)
  • packages/core/src/lib/organization-project/organization-project.controller.ts (3 hunks)
  • packages/core/src/lib/organization-project/organization-project.service.ts (3 hunks)
  • packages/ui-core/core/src/lib/resolvers/integration.resolver.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/src/lib/organization-project/organization-project.service.ts
  • apps/gauzy/src/app/pages/projects/guards/project-manager.guard.ts
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build
  • GitHub Check: test
🔇 Additional comments (4)
apps/gauzy/src/app/pages/projects/components/project-edit/edit.component.ts (1)

70-73: Remove debug console.log statement.

Remove the debug console.log statement to avoid exposing debug information in production.

-				console.log(integration);
packages/core/src/lib/organization-project/organization-project.controller.ts (1)

281-299: Well-implemented manager check endpoint!

The implementation is secure with proper parameter validation and well-documented with API metadata. The method aligns well with the permission management changes across the codebase.

apps/gauzy/src/app/pages/projects/components/project-list/list.component.ts (2)

284-286: Well-implemented manager check!

The implementation efficiently checks if the current user is a manager of the project.


618-620: Clean permission check implementation!

The method efficiently checks for multiple permissions using Array.every().

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/gauzy/src/app/pages/projects/guards/project-manager-permission.guard.ts (1)

41-41: Add type safety for route data access.

The direct access to route data properties could fail if the data structure is not as expected.

Consider adding an interface for the route data and using proper type guards:

interface ProjectRouteData {
  permissions?: {
    redirectTo?: string;
  };
}

// Then in the guard:
const routeData = route.data as ProjectRouteData;
const redirectPath = routeData?.permissions?.redirectTo || '/pages/dashboard';
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fba42ba and 06b26dd.

📒 Files selected for processing (2)
  • apps/gauzy/src/app/pages/projects/guards/project-manager-permission.guard.ts (1 hunks)
  • packages/ui-core/core/src/lib/resolvers/integration.resolver.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/ui-core/core/src/lib/resolvers/integration.resolver.ts
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: test
  • GitHub Check: Codacy Static Code Analysis
  • GitHub Check: build
🔇 Additional comments (1)
apps/gauzy/src/app/pages/projects/guards/project-manager-permission.guard.ts (1)

1-15: Well-structured guard implementation!

The class follows Angular best practices with proper dependency injection, typing, and scoping.

@samuelmbabhazi
Copy link
Contributor Author

@rahul This PR includes modifications to the project permission logic.

The goal was to grant managers the necessary permissions to edit, delete, and manage a project. Since a manager, in the context of a project, team, or task, is not considered a standalone role but is instead identified by the isManager flag, I applied the following logic:

Frontend:

  • When selecting a project, the frontend checks whether the logged-in user is a manager of that project or has the required permissions to manage it.
  • If the user is a manager, their permissions are temporarily added on the frontend to allow them to perform certain actions.
  • For editing, if the user needs to be redirected to the edit page, I created a new guard that verifies whether they are a manager or, if not, checks if they have the necessary permissions.

Note: I had to modify the logic of the integration resolver because it blocked the redirection for editing. (Another way to do this?)

Backend:

  • I created a new guard for projects that combines two checks: verifying if the user is a project manager or, if not, confirming they have the required permissions.

CC:@evereq

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants