Commit 39705221 by Belákovics Ádám

Add perms to all instance actions

parent beb0809d
Pipeline #856 passed with stage
in 1 minute 21 seconds
...@@ -12,26 +12,29 @@ class AuthorizationMixin(): ...@@ -12,26 +12,29 @@ class AuthorizationMixin():
def get_objects_with_perms(self, user, method, instance): def get_objects_with_perms(self, user, method, instance):
auth_params = self.authorization[method] auth_params = self.authorization[method]
if auth_params: if auth_params:
return get_objects_for_user(user, auth_params["perms"], instance) return get_objects_for_user(user, auth_params["filter"], instance)
else: else:
logger.error(f"Invalid method for authorization: {method}") logger.error(f"Invalid method for authorization: {method}")
return False
def has_perms_for_object(self, user, method, instance): def has_perms_for_object(self, user, method, instance):
auth_params = self.authorization[method] auth_params = self.authorization[method]
if auth_params: if auth_params:
for perm in auth_params["perms"]: for perm in auth_params["object"]:
if not user.has_perm(perm, instance): if not user.has_perm(perm, instance):
return False return False
return True return True
else: else:
logger.error(f"Invalid method for authorization: {method}") logger.error(f"Invalid method for authorization: {method}")
return False
def has_perms_for_model(self, user, method): def has_perms_for_model(self, user, method):
auth_params = self.authorization[method] auth_params = self.authorization[method]
if auth_params: if auth_params:
for perm in auth_params["perms"]: for perm in auth_params["model"]:
if not user.has_perm(perm): if not user.has_perm(perm):
return False return False
return True return True
else: else:
logger.error(f"Invalid method for authorization: {method}") logger.error(f"Invalid method for authorization: {method}")
return False
# Generated by Django 2.2.4 on 2019-08-30 12:27
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('instance', '0012_auto_20190829_0754'),
]
operations = [
migrations.AlterModelOptions(
name='instance',
options={'default_permissions': (), 'permissions': (('create_instance', 'Can create a new VM.'), ('create_template_from_instance', 'Can create template from instance.'), ('use_instance', 'Can access the VM connection info.'), ('operate_instance', 'Can use basic lifecycle methods of the VM.'), ('administer_instance', 'Can delete VM.'), ('access_console', 'Can access the graphical console of a VM.'), ('change_resources', 'Can change resources of a VM.'), ('manage_access', 'Can manage access rights for the VM.'), ('config_ports', 'Can configure port forwards.'))},
),
]
...@@ -86,6 +86,7 @@ class Instance(models.Model): ...@@ -86,6 +86,7 @@ class Instance(models.Model):
default_permissions = () default_permissions = ()
permissions = ( permissions = (
('create_instance', 'Can create a new VM.'), ('create_instance', 'Can create a new VM.'),
('create_template_from_instance', 'Can create template from instance.'),
('use_instance', 'Can access the VM connection info.'), ('use_instance', 'Can access the VM connection info.'),
('operate_instance', 'Can use basic lifecycle methods of the VM.'), ('operate_instance', 'Can use basic lifecycle methods of the VM.'),
('administer_instance', 'Can delete VM.'), ('administer_instance', 'Can delete VM.'),
......
...@@ -13,17 +13,18 @@ from authorization.mixins import AuthorizationMixin ...@@ -13,17 +13,18 @@ from authorization.mixins import AuthorizationMixin
authorization = { authorization = {
"list": {"auth_type": "filter", "perms": ["use_instance"]}, "list": {"filter": ["use_instance"]},
"create": {"auth_type": "class", "perms": ["instance.create_instance"]}, "create": {"model": ["instance.create_instance"]},
"retrieve": {"auth_type": "object", "perms": ["use_instance"]}, "retrieve": {"object": ["use_instance"]},
"destroy": {"auth_type": "object", "perms": ["administer_instance"]}, "destroy": {"object": ["administer_instance"]},
"template": {"auth_type": "object", "perms": ["use_instance"]}, "template": {"model": ["create_template_from_instance"],
"start": {"auth_type": "object", "perms": ["operate_instance"]}, "object": ["use_instance"]},
"stop": {"auth_type": "object", "perms": ["operate_instance"]}, "start": {"object": ["operate_instance"]},
"suspend": {"auth_type": "object", "perms": ["operate_instance"]}, "stop": {"object": ["operate_instance"]},
"wake_up": {"auth_type": "object", "perms": ["operate_instance"]}, "suspend": {"object": ["operate_instance"]},
"reset": {"auth_type": "object", "perms": ["operate_instance"]}, "wake_up": {"object": ["operate_instance"]},
"reboot": {"auth_type": "object", "perms": ["operate_instance"]}, "reset": {"object": ["operate_instance"]},
"reboot": {"object": ["operate_instance"]},
} }
...@@ -42,7 +43,6 @@ class InstanceViewSet(AuthorizationMixin, ViewSet): ...@@ -42,7 +43,6 @@ class InstanceViewSet(AuthorizationMixin, ViewSet):
return Response(InstanceSerializer(instances, many=True).data) return Response(InstanceSerializer(instances, many=True).data)
def create(self, request): def create(self, request):
# TODO: Put this logic in Mixin
if not self.has_perms_for_model(request.user, 'create'): if not self.has_perms_for_model(request.user, 'create'):
return Response({"error": "No permission to create Virtual Machine."}, return Response({"error": "No permission to create Virtual Machine."},
status=status.HTTP_401_UNAUTHORIZED) status=status.HTTP_401_UNAUTHORIZED)
...@@ -97,12 +97,21 @@ class InstanceViewSet(AuthorizationMixin, ViewSet): ...@@ -97,12 +97,21 @@ class InstanceViewSet(AuthorizationMixin, ViewSet):
def destroy(self, request, pk, format=None): def destroy(self, request, pk, format=None):
instance = self.get_object(pk) instance = self.get_object(pk)
if not self.has_perms_for_object(request.user, 'destroy', instance):
return Response({"error": "No permission to destroy the Virtual Machine."},
status=status.HTTP_401_UNAUTHORIZED)
instance.delete() instance.delete()
return Response(status=status.HTTP_204_NO_CONTENT) return Response(status=status.HTTP_204_NO_CONTENT)
@action(detail=True, methods=["post"]) @action(detail=True, methods=["post"])
def template(self, request, pk): def template(self, request, pk):
instance = self.get_object(pk) instance = self.get_object(pk)
if not self.has_perms_for_model(request.user, 'template'):
return Response({"error": "No permission to create template from instance."},
status=status.HTTP_401_UNAUTHORIZED)
if not self.has_perms_for_object(request.user, 'template', instance):
return Response({"error": "No permission to access the Virtual Machine."},
status=status.HTTP_401_UNAUTHORIZED)
serializer = InstanceFromTemplateSerializer(data=request.data) serializer = InstanceFromTemplateSerializer(data=request.data)
serializer.is_valid(raise_exception=True) serializer.is_valid(raise_exception=True)
data = serializer.validated_data data = serializer.validated_data
...@@ -116,8 +125,10 @@ class InstanceViewSet(AuthorizationMixin, ViewSet): ...@@ -116,8 +125,10 @@ class InstanceViewSet(AuthorizationMixin, ViewSet):
@action(detail=True, methods=["POST"]) @action(detail=True, methods=["POST"])
def actions(self, request, pk): def actions(self, request, pk):
instance = self.get_object(pk) instance = self.get_object(pk)
if not self.has_perms_for_object(request.user, request.data["action"], instance):
return Response({"error": "No permission to use this action on the VM."},
status=status.HTTP_401_UNAUTHORIZED)
success = instance.execute_common_action(action=request.data["action"]) success = instance.execute_common_action(action=request.data["action"])
return Response(success) return Response(success)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment