kopia lustrzana https://github.com/OpenDroneMap/WebODM
Permissions working
rodzic
31006b9373
commit
1e4b7e751b
|
@ -1,8 +1,10 @@
|
||||||
from guardian.shortcuts import get_perms, get_users_with_perms
|
from guardian.shortcuts import get_perms, get_users_with_perms, assign_perm, remove_perm
|
||||||
from rest_framework import serializers, viewsets
|
from rest_framework import serializers, viewsets
|
||||||
from rest_framework.decorators import detail_route
|
from rest_framework.decorators import detail_route
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
from rest_framework import status
|
from rest_framework import status
|
||||||
|
from django.db import transaction
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
from app import models
|
from app import models
|
||||||
from .tasks import TaskIDsSerializer
|
from .tasks import TaskIDsSerializer
|
||||||
|
@ -76,4 +78,54 @@ class ProjectViewSet(viewsets.ModelViewSet):
|
||||||
'owner': project.owner == user,
|
'owner': project.owner == user,
|
||||||
'permissions': normalized_perm_names(perms[user])})
|
'permissions': normalized_perm_names(perms[user])})
|
||||||
|
|
||||||
return Response(result, status=status.HTTP_200_OK)
|
return Response(result, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
@detail_route(methods=['post'])
|
||||||
|
def edit(self, request, pk=None):
|
||||||
|
project = get_and_check_project(request, pk, ('change_project', ))
|
||||||
|
|
||||||
|
try:
|
||||||
|
with transaction.atomic():
|
||||||
|
project.name = request.data.get('name')
|
||||||
|
project.description = request.data.get('description')
|
||||||
|
project.save()
|
||||||
|
|
||||||
|
form_perms = request.data.get('permissions')
|
||||||
|
if form_perms is not None:
|
||||||
|
# Build perms map (ignore owners, empty usernames)
|
||||||
|
perms_map = {}
|
||||||
|
for perm in form_perms:
|
||||||
|
if not perm.get('owner') and perm.get('username'):
|
||||||
|
perms_map[perm['username']] = perm['permissions']
|
||||||
|
|
||||||
|
db_perms = get_users_with_perms(project, attach_perms=True, with_group_users=False)
|
||||||
|
|
||||||
|
# Check users to remove
|
||||||
|
for user in db_perms:
|
||||||
|
|
||||||
|
# Never modify owner permissions
|
||||||
|
if project.owner == user:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if perms_map.get(user.username) is None:
|
||||||
|
for p in db_perms[user]:
|
||||||
|
remove_perm(p, user, project)
|
||||||
|
|
||||||
|
# Check users to add/edit
|
||||||
|
for username in perms_map:
|
||||||
|
for p in ["add", "change", "delete", "view"]:
|
||||||
|
perm = p + "_project"
|
||||||
|
user = User.objects.get(username=username)
|
||||||
|
|
||||||
|
# Has permission in database but not in form?
|
||||||
|
if user.has_perm(perm, project) and not p in perms_map[username]:
|
||||||
|
remove_perm(perm, user, project)
|
||||||
|
|
||||||
|
# Has permission in form but not in database?
|
||||||
|
elif p in perms_map[username] and not user.has_perm(perm, project):
|
||||||
|
assign_perm(perm, user, project)
|
||||||
|
|
||||||
|
except User.DoesNotExist as e:
|
||||||
|
return Response({'error': _("Invalid user in permissions list")}, status=status.HTTP_400_BAD_REQUEST)
|
||||||
|
|
||||||
|
return Response({'success': True}, status=status.HTTP_200_OK)
|
|
@ -53,6 +53,12 @@ class EditPermissionsPanel extends React.Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPermissions = () => {
|
||||||
|
// Cleanup temporary objects then return
|
||||||
|
this.state.permissions.forEach(perm => delete(perm.autocomplete));
|
||||||
|
return this.state.permissions;
|
||||||
|
}
|
||||||
|
|
||||||
autocomplete = (perm) => {
|
autocomplete = (perm) => {
|
||||||
if (this.validateReq){
|
if (this.validateReq){
|
||||||
this.validateReq.abort();
|
this.validateReq.abort();
|
||||||
|
|
|
@ -65,10 +65,16 @@ class EditProjectDialog extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormData(){
|
getFormData(){
|
||||||
return {
|
const res = {
|
||||||
name: this.state.name,
|
name: this.state.name,
|
||||||
descr: this.state.descr,
|
descr: this.state.descr,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (this.editPermissionsPanel){
|
||||||
|
res.permissions = this.editPermissionsPanel.getPermissions();
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
onShow(){
|
onShow(){
|
||||||
|
|
|
@ -112,7 +112,7 @@ class FormDialog extends React.Component {
|
||||||
this.serverRequest = this.props.saveAction(formData);
|
this.serverRequest = this.props.saveAction(formData);
|
||||||
if (this.serverRequest){
|
if (this.serverRequest){
|
||||||
this.serverRequest.fail(e => {
|
this.serverRequest.fail(e => {
|
||||||
this.setState({error: e.message || (e.responseJSON || {}).detail || e.responseText || _("Could not apply changes")});
|
this.setState({error: e.message || (e.responseJSON || {}).detail || (e.responseJSON || {}).error || e.responseText || _("Could not apply changes")});
|
||||||
}).always(() => {
|
}).always(() => {
|
||||||
this.setState({saving: false});
|
this.setState({saving: false});
|
||||||
this.serverRequest = null;
|
this.serverRequest = null;
|
||||||
|
|
|
@ -378,14 +378,15 @@ class ProjectListItem extends React.Component {
|
||||||
|
|
||||||
updateProject(project){
|
updateProject(project){
|
||||||
return $.ajax({
|
return $.ajax({
|
||||||
url: `/api/projects/${this.state.data.id}/`,
|
url: `/api/projects/${this.state.data.id}/edit/`,
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
name: project.name,
|
name: project.name,
|
||||||
description: project.descr,
|
description: project.descr,
|
||||||
|
permissions: project.permissions
|
||||||
}),
|
}),
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
type: 'PATCH'
|
type: 'POST'
|
||||||
}).done(() => {
|
}).done(() => {
|
||||||
this.refresh();
|
this.refresh();
|
||||||
});
|
});
|
||||||
|
|
Ładowanie…
Reference in New Issue