Skip to content

Commit 9326a7e

Browse files
committed
Refactor permission handling in ProjectViewSet to clarify access levels for different user roles and update project creation logic to set the creator as the project owner. Enhance error handling in createDefaultProject method in App.vue to provide more informative alerts based on specific error conditions.
1 parent 11f849c commit 9326a7e

2 files changed

Lines changed: 33 additions & 23 deletions

File tree

backend/core/views.py

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,28 @@ class ProjectViewSet(viewsets.ModelViewSet):
4040
permission_classes = [IsAuthenticated] # Default for list and create
4141

4242
def get_permissions(self):
43-
if self.action == 'retrieve':
44-
# For retrieve, user must be at least a viewer
45-
return [IsAuthenticated(), IsProjectViewerOrHigher()]
46-
elif self.action in ['update', 'partial_update', 'destroy']:
47-
# For modifications, user must be a manager or owner
48-
return [IsAuthenticated(), IsProjectManager()]
49-
# For list, create, and other actions, IsAuthenticated is sufficient
50-
# as get_queryset and perform_create handle specifics.
43+
"""
44+
Instantiates and returns the list of permissions that this view requires.
45+
Owners/Managers can do anything. Developers can read. Authenticated users can list/create.
46+
"""
47+
if self.action in ['list', 'create']:
48+
self.permission_classes = [permissions.IsAuthenticated] # Any authenticated user can list or create projects
49+
elif self.action in ['retrieve', 'update', 'partial_update', 'destroy']:
50+
# For specific project instances, check if user is owner or manager
51+
self.permission_classes = [permissions.IsAuthenticated, IsProjectOwner]
52+
else:
53+
# Default to deny all for any other actions
54+
self.permission_classes = [permissions.DenyAll]
5155
return super().get_permissions()
5256

5357
def perform_create(self, serializer):
54-
project = serializer.save(owner=self.request.user)
55-
# Automatically make the creator a 'manager' of the project
56-
ProjectMembership.objects.create(
57-
user=self.request.user,
58-
project=project,
59-
role=ProjectMembership.Role.MANAGER
60-
)
58+
"""Ensure the user creating the project is set as its owner."""
59+
project = serializer.save(owner=self.request.user) # Pass owner directly
60+
# Create a ProjectMembership for the creator as 'owner'
61+
ProjectMembership.objects.create(user=self.request.user, project=project, role='owner')
62+
# The direct owner field on the project model is now set by serializer.save()
63+
# project.owner = self.request.user # This line is no longer strictly needed if owner is passed in save
64+
# project.save() # And this save is also not needed as the first save includes the owner
6165

6266
def get_queryset(self):
6367
user = self.request.user

frontend/src/App.vue

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,25 @@ export default {
7373
this.currentProjectIdForConfigManager = projectId;
7474
},
7575
async createDefaultProject() {
76-
const PROJECT_API_URL = '/api/v1/core/projects/';
77-
console.log('Attempting to create default project...');
7876
try {
79-
const response = await axios.post(PROJECT_API_URL, { name: 'Default Project' });
77+
const response = await axios.post('/api/v1/core/projects/', { name: 'Default Project' });
8078
console.log('Default project created:', response.data);
81-
// Trigger project list refresh in ScanRunner
82-
if (this.$refs.scanRunner) {
79+
alert('Default Project created successfully! The project list will refresh.');
80+
// Refresh the project list in ScanRunner, assuming ScanRunner component has a ref and a method to fetch projects
81+
if (this.$refs.scanRunner && typeof this.$refs.scanRunner.fetchProjects === 'function') {
8382
this.$refs.scanRunner.fetchProjects();
83+
} else {
84+
console.warn('ScanRunner component or fetchProjects method not available.');
85+
// Optionally, emit an event that a parent component or global state manager can listen to
86+
// this.$root.$emit('projectListShouldRefresh'); // Example if using root instance as event bus
8487
}
85-
alert('Default Project created successfully! The project list will refresh.');
8688
} catch (error) {
87-
console.error('Error creating default project:', error.response || error.message);
88-
alert(`Failed to create default project: ${error.response?.data?.detail || error.message}`);
89+
console.error('Failed to create default project:', error);
90+
if (error.response && error.response.data && error.response.data.name && error.response.data.name[0].includes('project with this name already exists')) {
91+
alert('Failed to create default project: A project with the name "Default Project" already exists.');
92+
} else {
93+
alert('Failed to create default project: Request failed with status code ' + (error.response ? error.response.status : 'unknown'));
94+
}
8995
}
9096
}
9197
}

0 commit comments

Comments
 (0)