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

Permission class added for dynamics #58

Merged
merged 2 commits into from
Dec 20, 2023
Merged

Conversation

ruuushhh
Copy link
Contributor

@ruuushhh ruuushhh commented Dec 19, 2023

Summary by CodeRabbit

  • Refactor
    • Streamlined permissions by adjusting default settings for API access.
    • Removed unused entry from DEFAULT_PERMISSION_CLASSES in settings.py.
    • Introduced WorkspacePermissions class in permissions.py for workspace permission checks.
    • Implemented IsAuthenticatedForTest class in permissions.py for custom authentication during end-to-end tests.

@ruuushhh ruuushhh self-assigned this Dec 19, 2023
Copy link

coderabbitai bot commented Dec 19, 2023

Walkthrough

The update to the settings.py file within ms_business_central_api reflects a change in permission handling. A specific permission class, WorkspacePermissions, which was previously part of the default permissions set for the REST framework, has been commented out, leaving only the generic IsAuthenticated check active.

Changes

File Path Change Summary
.../ms_business_central_api/settings.py Commented out WorkspacePermissions in DEFAULT_PERMISSION_CLASSES.

Poem

In the code where rabbits hop,
A line was silenced with a bop.
🐰 Permissions shift and sway,
"Hop safely, friends!" is what they say.

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 X ?


Tips

Chat with CodeRabbit Bot (@coderabbitai)

  • You can reply to a review comment made by CodeRabbit.
  • You can tag CodeRabbit on specific lines of code or files in the PR by tagging @coderabbitai in a comment.
  • You can tag @coderabbitai in a PR comment and ask one-off questions about the PR and the codebase. Use quoted replies to pass the context for follow-up questions.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • The JSON schema for the configuration file is available here.
  • 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/coderabbit-overrides.v2.json

Copy link

@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.

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 21bc0b9 and 283e34e.
Files selected for processing (1)
  • ms_business_central_api/settings.py (1 hunks)
Files skipped from review due to trivial changes (1)
  • ms_business_central_api/settings.py

Copy link

Tests Skipped Failures Errors Time
47 0 💤 0 ❌ 0 🔥 4.283s ⏱️

Copy link

Tests Skipped Failures Errors Time
47 0 💤 0 ❌ 0 🔥 4.269s ⏱️

Copy link

Tests Skipped Failures Errors Time
47 0 💤 0 ❌ 0 🔥 4.158s ⏱️

Copy link

@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.

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 283e34e and 03de595.
Files selected for processing (1)
  • apps/workspaces/permissions.py (1 hunks)
Additional comments: 1
apps/workspaces/permissions.py (1)
  • 1-52: Verify that the PR title accurately reflects the changes made. The title suggests a new permission class has been added, but the provided hunk and summary indicate the modification and removal of existing classes.

Comment on lines +12 to +34
class WorkspacePermissions(permissions.BasePermission):
"""
Permission check for users <> workspaces
"""

def validate_and_cache(self, workspace_users, user: User, workspace_id: str, cache_users: bool = False):
if user.id in workspace_users:
if cache_users:
cache.set(workspace_id, workspace_users, 172800)
return True

return False

def has_permission(self, request, view):
workspace_id = str(view.kwargs.get('workspace_id'))
user = request.user
workspace_users = cache.get(workspace_id)

if workspace_users:
return self.validate_and_cache(workspace_users, user, workspace_id)
else:
workspace_users = Workspace.objects.filter(pk=workspace_id).values_list('user', flat=True)
return self.validate_and_cache(workspace_users, user, workspace_id, True)
Copy link

Choose a reason for hiding this comment

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

The WorkspacePermissions class introduces caching logic for workspace users. Ensure that the cache key is unique and cannot collide with other cache entries. Also, consider handling potential exceptions when interacting with the cache or the database.

+ try:
+     # Existing code for caching and database interaction
+ except SomeSpecificException as e:
+     # Handle exceptions appropriately
+     pass

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
class WorkspacePermissions(permissions.BasePermission):
"""
Permission check for users <> workspaces
"""
def validate_and_cache(self, workspace_users, user: User, workspace_id: str, cache_users: bool = False):
if user.id in workspace_users:
if cache_users:
cache.set(workspace_id, workspace_users, 172800)
return True
return False
def has_permission(self, request, view):
workspace_id = str(view.kwargs.get('workspace_id'))
user = request.user
workspace_users = cache.get(workspace_id)
if workspace_users:
return self.validate_and_cache(workspace_users, user, workspace_id)
else:
workspace_users = Workspace.objects.filter(pk=workspace_id).values_list('user', flat=True)
return self.validate_and_cache(workspace_users, user, workspace_id, True)
class WorkspacePermissions(permissions.BasePermission):
"""
Permission check for users <> workspaces
"""
def validate_and_cache(self, workspace_users, user: User, workspace_id: str, cache_users: bool = False):
try:
if user.id in workspace_users:
if cache_users:
cache.set(workspace_id, workspace_users, 172800)
return True
return False
except SomeSpecificException as e:
# Handle exceptions appropriately
pass
def has_permission(self, request, view):
try:
workspace_id = str(view.kwargs.get('workspace_id'))
user = request.user
workspace_users = cache.get(workspace_id)
if workspace_users:
return self.validate_and_cache(workspace_users, user, workspace_id)
else:
workspace_users = Workspace.objects.filter(pk=workspace_id).values_list('user', flat=True)
return self.validate_and_cache(workspace_users, user, workspace_id, True)
except SomeSpecificException as e:
# Handle exceptions appropriately
pass

Comment on lines +37 to +52
class IsAuthenticatedForTest(permissions.BasePermission):
"""
Custom auth for preparing a workspace for e2e tests
"""

def has_permission(self, request, view):
# Client sends a token in the header, which we decrypt and compare with the Client Secret
cipher_suite = Fernet(settings.ENCRYPTION_KEY)
try:
decrypted_password = cipher_suite.decrypt(request.headers['X-E2E-Tests-Client-ID'].encode('utf-8')).decode('utf-8')
if decrypted_password == settings.E2E_TESTS_CLIENT_SECRET:
return True
except Exception:
return False

return False
Copy link

Choose a reason for hiding this comment

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

The IsAuthenticatedForTest class uses encryption keys to decrypt a client ID. Ensure that the ENCRYPTION_KEY and E2E_TESTS_CLIENT_SECRET are securely managed and that the decryption process does not introduce security vulnerabilities. Additionally, catching a generic Exception is not a best practice; catch specific exceptions instead.
[SECURITY]

- except Exception:
+ except (Fernet.InvalidToken, KeyError, AttributeError) as e:
+     # Log the error for debugging purposes
+     logger.error(f"Error during decryption: {e}")

Committable suggestion

IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
class IsAuthenticatedForTest(permissions.BasePermission):
"""
Custom auth for preparing a workspace for e2e tests
"""
def has_permission(self, request, view):
# Client sends a token in the header, which we decrypt and compare with the Client Secret
cipher_suite = Fernet(settings.ENCRYPTION_KEY)
try:
decrypted_password = cipher_suite.decrypt(request.headers['X-E2E-Tests-Client-ID'].encode('utf-8')).decode('utf-8')
if decrypted_password == settings.E2E_TESTS_CLIENT_SECRET:
return True
except Exception:
return False
return False
class IsAuthenticatedForTest(permissions.BasePermission):
"""
Custom auth for preparing a workspace for e2e tests
"""
def has_permission(self, request, view):
# Client sends a token in the header, which we decrypt and compare with the Client Secret
cipher_suite = Fernet(settings.ENCRYPTION_KEY)
try:
decrypted_password = cipher_suite.decrypt(request.headers['X-E2E-Tests-Client-ID'].encode('utf-8')).decode('utf-8')
if decrypted_password == settings.E2E_TESTS_CLIENT_SECRET:
return True
except (Fernet.InvalidToken, KeyError, AttributeError) as e:
# Log the error for debugging purposes
logger.error(f"Error during decryption: {e}")
return False
return False

@ruuushhh ruuushhh merged commit b965983 into master Dec 20, 2023
1 check passed
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.

4 participants