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

feat(designer): endpoint to get UserOrgPermissions #14389

Merged
merged 9 commits into from
Jan 14, 2025

Conversation

framitdavid
Copy link
Collaborator

@framitdavid framitdavid commented Jan 9, 2025

Description

This PR introduces a new backend endpoint to verify if a user has the necessary permissions to create a new app/repository for their organization. The endpoint will be used by the frontend to check the user's access rights before enabling the "Submit" button for repository/app creation. This proactive validation helps prevent errors and ensures a smoother user experience.

Related Issue(s)

Verification

  • Your code builds clean without any errors or warnings
  • Manual testing done (required)
  • Relevant automated test added (if you find this hard, leave it and we'll help out)

Manual testing

Manual tested that I cannot create repos for orgs I don't belong to

image

Manual tested that I can create repos for orgs I belongs to

image

Manual tested that I can create repo if the owner is myself.

image

Frontend

The frontend changes and video of how it looks can be seen within the PR description of the following PR: #14395

Summary by CodeRabbit

  • New Features

    • Added a new endpoint to check user permissions for creating organization repositories
    • Introduced user organization permission validation mechanism
  • Bug Fixes

    • Corrected error logging message in Gitea API wrapper
  • Refactor

    • Improved organization name validation process
    • Enhanced dependency injection configuration
    • Streamlined user permission checking logic
  • Tests

    • Added comprehensive test coverage for new user service and organization validation functionality

@github-actions github-actions bot added solution/studio/designer Issues related to the Altinn Studio Designer solution. backend labels Jan 9, 2025
@github-actions github-actions bot added the quality/testing Tests that are missing, needs to be created or could be improved. label Jan 9, 2025
@framitdavid framitdavid changed the title feat(desinger): endpoint to get UserRepositoryPermissions (Work In Progress) feat(desinger): endpoint to get UserRepositoryPermissions Jan 9, 2025
@framitdavid framitdavid changed the title feat(desinger): endpoint to get UserRepositoryPermissions feat(designer): endpoint to get UserRepositoryPermissions Jan 9, 2025
@framitdavid framitdavid changed the title feat(designer): endpoint to get UserRepositoryPermissions feat(designer): endpoint to get UserOrgPermissions Jan 9, 2025
Copy link
Contributor

coderabbitai bot commented Jan 14, 2025

📝 Walkthrough

Walkthrough

The pull request introduces a comprehensive enhancement to the user permission and organization repository creation functionality in the Altinn Studio Designer backend. The changes include adding a new UserService, creating an AltinnOrgContext, implementing a new endpoint for checking user organization permissions, and updating various supporting classes and interfaces. The modifications enable more granular control over repository creation permissions, with new validation mechanisms and service implementations to support this feature.

Changes

File Change Summary
backend/src/Designer/Controllers/UserController.cs - Added _userService field
- Updated constructor to inject IUserService
- Added HasAccessToCreateRepository method to check user org permissions
backend/src/Designer/Helpers/Guard.cs - Added AssertValidateOrganization method to validate organization names
backend/src/Designer/Infrastructure/ServiceRegistration.cs - Registered UserService for IUserService with scoped lifetime
backend/src/Designer/Models/... - Added AltinnOrgContext class with org and developer name properties
- Updated AltinnRepoContext validation logic
- Created UserOrgPermission DTO with CanCreateOrgRepo property
backend/src/Designer/RepositoryClient/Model/Team.cs - Added CanCreateOrgRepo property
backend/src/Designer/Services/... - Implemented UserService with methods to check org repository creation permissions
- Created IUserService interface
backend/tests/Designer.Tests/... - Added integration and unit tests for new functionality
- Created UserServiceTests and updated UserControllerGiteaIntegrationTests
- Added GuardTests for organization name validation

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.

Copy link
Collaborator

@mirkoSekulic mirkoSekulic left a comment

Choose a reason for hiding this comment

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

👏

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: 8

♻️ Duplicate comments (1)
backend/src/Designer/Services/Implementation/UserService.cs (1)

34-35: ⚠️ Potential issue

Use short-circuit logic to prevent unnecessary API calls.

The current implementation might evaluate both conditions even when the first one is true. Use short-circuit logic with || instead of |.

🧹 Nitpick comments (7)
backend/src/Designer/Models/Dto/UserOrgPermission.cs (1)

3-6: Add XML documentation for the DTO.

Since this DTO is part of the API contract, please add XML documentation to describe the class and its property:

+/// <summary>
+/// Represents user permissions for organization repository operations.
+/// </summary>
 public class UserOrgPermission
 {
+    /// <summary>
+    /// Gets or sets a value indicating whether the user can create repositories for the organization.
+    /// </summary>
     public bool CanCreateOrgRepo { get; set; }
 }
backend/src/Designer/Services/Interfaces/IUserService.cs (1)

7-10: Add XML documentation and support for cancellation.

  1. Add XML documentation for the interface and method.
  2. Consider adding CancellationToken parameter for proper async operation cancellation support.
+/// <summary>
+/// Service for managing user-related operations.
+/// </summary>
 public interface IUserService
 {
+    /// <summary>
+    /// Gets the user's permissions for an organization.
+    /// </summary>
+    /// <param name="altinnOrgContext">The organization context.</param>
+    /// <param name="cancellationToken">A token to cancel the async operation.</param>
+    /// <returns>The user's permissions for the organization.</returns>
-    public Task<UserOrgPermission> GetUserOrgPermission(AltinnOrgContext altinnOrgContext);
+    public Task<UserOrgPermission> GetUserOrgPermission(AltinnOrgContext altinnOrgContext, CancellationToken cancellationToken = default);
 }
backend/src/Designer/RepositoryClient/Model/Team.cs (1)

13-14: Add XML documentation and improve property organization.

The new property should follow the existing documentation pattern and be properly organized with other properties.

-        public bool CanCreateOrgRepo { get; set; }
+        /// <summary>
+        /// Gets or sets a value indicating whether the team can create organization repositories.
+        /// </summary>
+        public bool CanCreateOrgRepo { get; set; }
backend/src/Designer/Models/AltinnOrgContext.cs (1)

5-23: Add XML documentation and strengthen input validation.

  1. Add XML documentation for the class, properties, and methods.
  2. Consider adding input validation in the factory method for defensive programming.
+/// <summary>
+/// Represents the context for Altinn organization operations.
+/// </summary>
 public class AltinnOrgContext
 {
+    /// <summary>
+    /// Gets the organization identifier.
+    /// </summary>
     public string Org { get; }
+
+    /// <summary>
+    /// Gets the developer's username.
+    /// </summary>
     public string DeveloperName { get; }

     private AltinnOrgContext(string org, string developerName)
     {
         Guard.AssertValidateOrganization(org);
         Org = org;

         Guard.AssertArgumentNotNullOrWhiteSpace(developerName, nameof(developerName));
         DeveloperName = developerName;
     }

+    /// <summary>
+    /// Creates a new instance of the <see cref="AltinnOrgContext"/> class.
+    /// </summary>
+    /// <param name="org">The organization identifier.</param>
+    /// <param name="developerName">The developer's username.</param>
+    /// <returns>A new instance of <see cref="AltinnOrgContext"/>.</returns>
+    /// <exception cref="ArgumentException">Thrown when inputs are invalid.</exception>
     public static AltinnOrgContext FromOrg(string org, string developerName)
     {
+        if (string.IsNullOrWhiteSpace(org))
+            throw new ArgumentException("Organization cannot be null or empty.", nameof(org));
+        if (string.IsNullOrWhiteSpace(developerName))
+            throw new ArgumentException("Developer name cannot be null or empty.", nameof(developerName));
+
         return new AltinnOrgContext(org, developerName);
     }
 }
backend/src/Designer/Services/Implementation/UserService.cs (1)

11-18: Add XML documentation for public members.

Add XML documentation for the class and constructor to improve API documentation.

+/// <summary>
+/// Service for managing user-related operations.
+/// </summary>
 public class UserService : IUserService
 {
     private readonly IGitea _giteaApi;

+    /// <summary>
+    /// Initializes a new instance of the <see cref="UserService"/> class.
+    /// </summary>
+    /// <param name="giteaApi">The Gitea API client.</param>
     public UserService(IGitea giteaApi)
     {
         _giteaApi = giteaApi;
     }
backend/tests/Designer.Tests/Helpers/GuardTests.cs (1)

55-63: Add more test cases for organization name validation.

Consider adding test cases for:

  1. Organization names with spaces (e.g., "Organization Name")
  2. Organization names with hyphens (e.g., "org-name")
  3. Organization names with numbers (e.g., "org123")
 [Theory]
 [InlineData(null)]
 [InlineData("")]
 [InlineData(" ")]
 [InlineData("Invalid@OrgName")]
+[InlineData("Organization Name")]
+[InlineData("org name")]
+[InlineData("org-name")]
+[InlineData("123org")]
 public void AssertValidateOrganization_InvalidOrg_ShouldThrowException(string org)
backend/src/Designer/Services/Implementation/GiteaAPIWrapper/GiteaAPIWrapper.cs (1)

Line range hint 1-1000: Consider standardizing error handling across all Gitea API operations.

The codebase shows inconsistent error handling patterns across different methods. Some return null, others return empty collections, and some include status codes in the response. Given this service's critical role in permission management, consider:

  1. Implementing a consistent error handling strategy
  2. Using custom exception types for different error scenarios
  3. Including relevant context in error responses
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a514966 and eb4921d.

📒 Files selected for processing (13)
  • backend/src/Designer/Controllers/UserController.cs (3 hunks)
  • backend/src/Designer/Helpers/Guard.cs (1 hunks)
  • backend/src/Designer/Infrastructure/ServiceRegistration.cs (1 hunks)
  • backend/src/Designer/Models/AltinnOrgContext.cs (1 hunks)
  • backend/src/Designer/Models/AltinnRepoContext.cs (2 hunks)
  • backend/src/Designer/Models/Dto/UserOrgPermission.cs (1 hunks)
  • backend/src/Designer/RepositoryClient/Model/Team.cs (1 hunks)
  • backend/src/Designer/Services/Implementation/GiteaAPIWrapper/GiteaAPIWrapper.cs (1 hunks)
  • backend/src/Designer/Services/Implementation/UserService.cs (1 hunks)
  • backend/src/Designer/Services/Interfaces/IUserService.cs (1 hunks)
  • backend/tests/Designer.Tests/GiteaIntegrationTests/UserControllerGiteaIntegrationTests.cs (4 hunks)
  • backend/tests/Designer.Tests/Helpers/GuardTests.cs (3 hunks)
  • backend/tests/Designer.Tests/Services/UserServiceTests.cs (1 hunks)
🧰 Additional context used
🪛 GitHub Check: Run dotnet build and test (macos-latest)
backend/src/Designer/Controllers/UserController.cs

[warning] 30-30:
Parameter 'userService' has no matching param tag in the XML comment for 'UserController.UserController(IGitea, IAntiforgery, IUserService)' (but other parameters do)


[warning] 30-30:
Parameter 'userService' has no matching param tag in the XML comment for 'UserController.UserController(IGitea, IAntiforgery, IUserService)' (but other parameters do)

🪛 GitHub Check: Run integration tests against actual gitea and db
backend/src/Designer/Controllers/UserController.cs

[warning] 30-30:
Parameter 'userService' has no matching param tag in the XML comment for 'UserController.UserController(IGitea, IAntiforgery, IUserService)' (but other parameters do)


[warning] 30-30:
Parameter 'userService' has no matching param tag in the XML comment for 'UserController.UserController(IGitea, IAntiforgery, IUserService)' (but other parameters do)

⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build environment and run e2e test
  • GitHub Check: Run dotnet build and test (windows-latest)
  • GitHub Check: Run dotnet build and test (ubuntu-latest)
  • GitHub Check: Analyze
🔇 Additional comments (5)
backend/src/Designer/Models/AltinnOrgContext.cs (1)

12-12: Verify the organization validation logic.

The Guard.AssertValidateOrganization method is used for validation, but its implementation is not visible in the provided context.

✅ Verification successful

Organization validation logic is properly implemented

  • The validation uses a regex pattern to ensure valid organization names
  • Includes null/empty checks with appropriate error messages
  • Has comprehensive test coverage including valid and invalid cases
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for Guard.AssertValidateOrganization implementation
ast-grep --pattern 'AssertValidateOrganization($_) { $$$ }'

Length of output: 61


Script:

#!/bin/bash
# Search for AssertValidateOrganization method using ripgrep
rg -l "AssertValidateOrganization"

# Search for Guard class definition
ast-grep --pattern 'class Guard { $$$ }'

# Search for files containing validation logic
fd -t f "(Guard|Validate|Organization)"

Length of output: 2038


Script:

#!/bin/bash
# Get the Guard class implementation
rg -A 10 "AssertValidateOrganization" backend/src/Designer/Helpers/Guard.cs

# Get the test cases
rg -A 10 "AssertValidateOrganization" backend/tests/Designer.Tests/Helpers/GuardTests.cs

# Get usage context from AltinnRepoContext
rg -A 5 "AssertValidateOrganization" backend/src/Designer/Models/AltinnRepoContext.cs

Length of output: 1336

backend/src/Designer/Models/AltinnRepoContext.cs (1)

23-27: LGTM! Good refactoring of validation logic.

Moving organization validation to the Guard class promotes code reuse and consistency across the codebase.

backend/src/Designer/Infrastructure/ServiceRegistration.cs (1)

57-57: LGTM!

The UserService is correctly registered with a scoped lifetime, consistent with other similar services.

backend/src/Designer/Services/Implementation/GiteaAPIWrapper/GiteaAPIWrapper.cs (2)

81-87: LGTM! Improved JSON deserialization with proper property naming policy.

The change to use JsonSerializerOptions with SnakeCaseLower naming policy ensures correct mapping between Gitea API's snake_case response and the Team model's PascalCase properties.


91-91: LGTM! Fixed typo in error message.

Corrected the error message from "Cold" to "Could".

@framitdavid framitdavid added the skip-manual-testing PRs that do not need to be tested manually label Jan 14, 2025
@framitdavid
Copy link
Collaborator Author

I have tested it locally, and it will undergo full testing with the frontend PR afterwards as well. 😊

@framitdavid framitdavid merged commit 3784722 into main Jan 14, 2025
14 checks passed
@framitdavid framitdavid deleted the feat/newEndpointToFetchUserRepositoryPermissions branch January 14, 2025 12:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend quality/testing Tests that are missing, needs to be created or could be improved. skip-manual-testing PRs that do not need to be tested manually solution/studio/designer Issues related to the Altinn Studio Designer solution. team/studio-core
Projects
Status: ✅ Done
Development

Successfully merging this pull request may close these issues.

Improve error message for users with insufficient rights
2 participants