Commit 3ec83939 by Belákovics Ádám

Merge branch 'instance_auth' into 'DEV'

Instance auth

See merge request !17
parents c0d7f992 befe5fa1
Pipeline #862 passed with stage
in 1 minute 22 seconds
......@@ -17,6 +17,7 @@ django-cors-headers = "*"
openstacksdk = "*"
python-novaclient = "*"
keystoneauth1 = "*"
django-guardian = "*"
djoser = "*"
[requires]
......
{
"_meta": {
"hash": {
"sha256": "8cb2efb1cfa79de96297c90953faf757011ca1f1ff4784ac05226a249001e1f5"
"sha256": "dd7bfbb33d07cbcc96d1f3b1f838538dba41f3eb0bf5279381714b4b9abf90d7"
},
"pipfile-spec": 6,
"requires": {
......@@ -135,6 +135,14 @@
"index": "pypi",
"version": "==3.0.2"
},
"django-guardian": {
"hashes": [
"sha256:965d3a1e20fb3639e0ab16b0e768611f694c02d762916f80d9f3f7520c16aa7b",
"sha256:e8c4556c4e145028a5dcfd7b2611d52e1ac104af562017ce17c3f67e47a62693"
],
"index": "pypi",
"version": "==2.0.0"
},
"django-templated-mail": {
"hashes": [
"sha256:8db807effebb42a532622e2d142dfd453dafcd0d7794c4c3332acb90656315f9",
......
from django.contrib.auth.models import Permission
from django.contrib import admin
admin.site.register(Permission)
from django.apps import AppConfig
class AuthorizationConfig(AppConfig):
name = 'authorization'
from guardian.shortcuts import get_objects_for_user
import logging
logger = logging.getLogger(__name__)
class AuthorizationMixin():
authorization = {}
def get_objects_with_perms(self, user, method, instance):
auth_params = self.authorization[method]
if auth_params:
return get_objects_for_user(user, auth_params["filter"], instance)
else:
logger.error(f"Invalid method for authorization: {method}")
return False
def has_perms_for_object(self, user, method, instance):
auth_params = self.authorization[method]
if auth_params:
for perm in auth_params["object"]:
if not user.has_perm(perm, instance):
return False
return True
else:
logger.error(f"Invalid method for authorization: {method}")
return False
def has_perms_for_model(self, user, method):
auth_params = self.authorization[method]
if auth_params:
for perm in auth_params["model"]:
if not user.has_perm(perm):
return False
return True
else:
logger.error(f"Invalid method for authorization: {method}")
return False
......@@ -2,6 +2,13 @@ from django.contrib import admin
from instance.models import Instance, Flavor, Lease
admin.site.register(Instance)
from guardian.admin import GuardedModelAdmin
class InstanceAdmin(GuardedModelAdmin):
pass
admin.site.register(Instance, InstanceAdmin)
admin.site.register(Flavor)
admin.site.register(Lease)
[{"model": "contenttypes.contenttype", "pk": 1, "fields": {"app_label": "admin", "model": "logentry"}}, {"model": "contenttypes.contenttype", "pk": 2, "fields": {"app_label": "auth", "model": "permission"}}, {"model": "contenttypes.contenttype", "pk": 3, "fields": {"app_label": "auth", "model": "group"}}, {"model": "contenttypes.contenttype", "pk": 4, "fields": {"app_label": "auth", "model": "user"}}, {"model": "contenttypes.contenttype", "pk": 5, "fields": {"app_label": "contenttypes", "model": "contenttype"}}, {"model": "contenttypes.contenttype", "pk": 6, "fields": {"app_label": "sessions", "model": "session"}}, {"model": "contenttypes.contenttype", "pk": 7, "fields": {"app_label": "authtoken", "model": "token"}}, {"model": "contenttypes.contenttype", "pk": 8, "fields": {"app_label": "guardian", "model": "groupobjectpermission"}}, {"model": "contenttypes.contenttype", "pk": 9, "fields": {"app_label": "guardian", "model": "userobjectpermission"}}, {"model": "contenttypes.contenttype", "pk": 10, "fields": {"app_label": "image", "model": "disk"}}, {"model": "contenttypes.contenttype", "pk": 11, "fields": {"app_label": "image", "model": "image"}}, {"model": "contenttypes.contenttype", "pk": 12, "fields": {"app_label": "instance", "model": "instance"}}, {"model": "contenttypes.contenttype", "pk": 13, "fields": {"app_label": "instance", "model": "flavor"}}, {"model": "contenttypes.contenttype", "pk": 14, "fields": {"app_label": "instance", "model": "lease"}}, {"model": "contenttypes.contenttype", "pk": 15, "fields": {"app_label": "template", "model": "basetemplate"}}, {"model": "contenttypes.contenttype", "pk": 16, "fields": {"app_label": "template", "model": "disktemplate"}}, {"model": "contenttypes.contenttype", "pk": 17, "fields": {"app_label": "template", "model": "imagetemplate"}}, {"model": "sessions.session", "pk": "70jxjk2wd7gvxd4u8nnf1e1l3ie7u3os", "fields": {"session_data": "NjE4NzBkZjdiYWIwNzNkYjg0MmFjMjBkMzI3OWRmYzc5YmNiNzFjYzp7Il9hdXRoX3VzZXJfaWQiOiIyIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiJhNzg5YTA3MjkxZmI1ODU1MWM5YWFjNWVjZDhiZmViZjQ4NDkyOWE1In0=", "expire_date": "2019-08-22T11:39:55.803Z"}}, {"model": "sessions.session", "pk": "7akwvw78xjpvkoc1w6mhco170q7ohx81", "fields": {"session_data": "ZjhlY2Q2YzVjNzU3YWUwZjFiNDMzNzg2Mjg0Yjk5OThlYTVmMGNiNzp7Il9hdXRoX3VzZXJfaWQiOiI0IiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiIyMjY4MmMzNzkxZWJjMjIzNjc5NjBhMzU3NmVlMWRhOGIzN2Y4ODkzIn0=", "expire_date": "2019-08-22T12:06:51.022Z"}}, {"model": "sessions.session", "pk": "8ckz81gn9rivtw3zdcqkfup4lznnh244", "fields": {"session_data": "NjE4NzBkZjdiYWIwNzNkYjg0MmFjMjBkMzI3OWRmYzc5YmNiNzFjYzp7Il9hdXRoX3VzZXJfaWQiOiIyIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiJhNzg5YTA3MjkxZmI1ODU1MWM5YWFjNWVjZDhiZmViZjQ4NDkyOWE1In0=", "expire_date": "2019-08-22T12:03:59.108Z"}}, {"model": "sessions.session", "pk": "jy21e8ygksos3pvb5t5dfilu1s94b0s2", "fields": {"session_data": "NjE4NzBkZjdiYWIwNzNkYjg0MmFjMjBkMzI3OWRmYzc5YmNiNzFjYzp7Il9hdXRoX3VzZXJfaWQiOiIyIiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiJhNzg5YTA3MjkxZmI1ODU1MWM5YWFjNWVjZDhiZmViZjQ4NDkyOWE1In0=", "expire_date": "2019-08-22T12:01:49.707Z"}}, {"model": "sessions.session", "pk": "qtpmb6wp5qvslpv465tnm4n23963n6ig", "fields": {"session_data": "ZjhlY2Q2YzVjNzU3YWUwZjFiNDMzNzg2Mjg0Yjk5OThlYTVmMGNiNzp7Il9hdXRoX3VzZXJfaWQiOiI0IiwiX2F1dGhfdXNlcl9iYWNrZW5kIjoiZGphbmdvLmNvbnRyaWIuYXV0aC5iYWNrZW5kcy5Nb2RlbEJhY2tlbmQiLCJfYXV0aF91c2VyX2hhc2giOiIyMjY4MmMzNzkxZWJjMjIzNjc5NjBhMzU3NmVlMWRhOGIzN2Y4ODkzIn0=", "expire_date": "2019-08-22T12:10:15.304Z"}}, {"model": "image.disk", "pk": 1, "fields": {"name": "Ubuntu 18.04", "remote_id": "bfc3fbdc-c4b8-46a5-8e71-feca9ba379f5"}}, {"model": "instance.lease", "pk": 1, "fields": {"name": "project", "description": "Project", "suspend_interval_in_sec": 50000, "delete_interval_in_sec": 50000}}, {"model": "instance.flavor", "pk": 1, "fields": {"name": "small", "description": "Small flavor", "remote_id": "d1", "ram": 512, "vcpu": 1, "initial_disk": 5, "priority": 1}}, {"model": "auth.permission", "pk": 1, "fields": {"name": "Can add log entry", "content_type": 1, "codename": "add_logentry"}}, {"model": "auth.permission", "pk": 2, "fields": {"name": "Can change log entry", "content_type": 1, "codename": "change_logentry"}}, {"model": "auth.permission", "pk": 3, "fields": {"name": "Can delete log entry", "content_type": 1, "codename": "delete_logentry"}}, {"model": "auth.permission", "pk": 4, "fields": {"name": "Can view log entry", "content_type": 1, "codename": "view_logentry"}}, {"model": "auth.permission", "pk": 5, "fields": {"name": "Can add permission", "content_type": 2, "codename": "add_permission"}}, {"model": "auth.permission", "pk": 6, "fields": {"name": "Can change permission", "content_type": 2, "codename": "change_permission"}}, {"model": "auth.permission", "pk": 7, "fields": {"name": "Can delete permission", "content_type": 2, "codename": "delete_permission"}}, {"model": "auth.permission", "pk": 8, "fields": {"name": "Can view permission", "content_type": 2, "codename": "view_permission"}}, {"model": "auth.permission", "pk": 9, "fields": {"name": "Can add group", "content_type": 3, "codename": "add_group"}}, {"model": "auth.permission", "pk": 10, "fields": {"name": "Can change group", "content_type": 3, "codename": "change_group"}}, {"model": "auth.permission", "pk": 11, "fields": {"name": "Can delete group", "content_type": 3, "codename": "delete_group"}}, {"model": "auth.permission", "pk": 12, "fields": {"name": "Can view group", "content_type": 3, "codename": "view_group"}}, {"model": "auth.permission", "pk": 13, "fields": {"name": "Can add user", "content_type": 4, "codename": "add_user"}}, {"model": "auth.permission", "pk": 14, "fields": {"name": "Can change user", "content_type": 4, "codename": "change_user"}}, {"model": "auth.permission", "pk": 15, "fields": {"name": "Can delete user", "content_type": 4, "codename": "delete_user"}}, {"model": "auth.permission", "pk": 16, "fields": {"name": "Can view user", "content_type": 4, "codename": "view_user"}}, {"model": "auth.permission", "pk": 17, "fields": {"name": "Can add content type", "content_type": 5, "codename": "add_contenttype"}}, {"model": "auth.permission", "pk": 18, "fields": {"name": "Can change content type", "content_type": 5, "codename": "change_contenttype"}}, {"model": "auth.permission", "pk": 19, "fields": {"name": "Can delete content type", "content_type": 5, "codename": "delete_contenttype"}}, {"model": "auth.permission", "pk": 20, "fields": {"name": "Can view content type", "content_type": 5, "codename": "view_contenttype"}}, {"model": "auth.permission", "pk": 21, "fields": {"name": "Can add session", "content_type": 6, "codename": "add_session"}}, {"model": "auth.permission", "pk": 22, "fields": {"name": "Can change session", "content_type": 6, "codename": "change_session"}}, {"model": "auth.permission", "pk": 23, "fields": {"name": "Can delete session", "content_type": 6, "codename": "delete_session"}}, {"model": "auth.permission", "pk": 24, "fields": {"name": "Can view session", "content_type": 6, "codename": "view_session"}}, {"model": "auth.permission", "pk": 25, "fields": {"name": "Can add Token", "content_type": 7, "codename": "add_token"}}, {"model": "auth.permission", "pk": 26, "fields": {"name": "Can change Token", "content_type": 7, "codename": "change_token"}}, {"model": "auth.permission", "pk": 27, "fields": {"name": "Can delete Token", "content_type": 7, "codename": "delete_token"}}, {"model": "auth.permission", "pk": 28, "fields": {"name": "Can view Token", "content_type": 7, "codename": "view_token"}}, {"model": "auth.permission", "pk": 29, "fields": {"name": "Can add group object permission", "content_type": 8, "codename": "add_groupobjectpermission"}}, {"model": "auth.permission", "pk": 30, "fields": {"name": "Can change group object permission", "content_type": 8, "codename": "change_groupobjectpermission"}}, {"model": "auth.permission", "pk": 31, "fields": {"name": "Can delete group object permission", "content_type": 8, "codename": "delete_groupobjectpermission"}}, {"model": "auth.permission", "pk": 32, "fields": {"name": "Can view group object permission", "content_type": 8, "codename": "view_groupobjectpermission"}}, {"model": "auth.permission", "pk": 33, "fields": {"name": "Can add user object permission", "content_type": 9, "codename": "add_userobjectpermission"}}, {"model": "auth.permission", "pk": 34, "fields": {"name": "Can change user object permission", "content_type": 9, "codename": "change_userobjectpermission"}}, {"model": "auth.permission", "pk": 35, "fields": {"name": "Can delete user object permission", "content_type": 9, "codename": "delete_userobjectpermission"}}, {"model": "auth.permission", "pk": 36, "fields": {"name": "Can view user object permission", "content_type": 9, "codename": "view_userobjectpermission"}}, {"model": "auth.permission", "pk": 37, "fields": {"name": "Can add disk", "content_type": 10, "codename": "add_disk"}}, {"model": "auth.permission", "pk": 38, "fields": {"name": "Can change disk", "content_type": 10, "codename": "change_disk"}}, {"model": "auth.permission", "pk": 39, "fields": {"name": "Can delete disk", "content_type": 10, "codename": "delete_disk"}}, {"model": "auth.permission", "pk": 40, "fields": {"name": "Can view disk", "content_type": 10, "codename": "view_disk"}}, {"model": "auth.permission", "pk": 41, "fields": {"name": "Can add image", "content_type": 11, "codename": "add_image"}}, {"model": "auth.permission", "pk": 42, "fields": {"name": "Can change image", "content_type": 11, "codename": "change_image"}}, {"model": "auth.permission", "pk": 43, "fields": {"name": "Can delete image", "content_type": 11, "codename": "delete_image"}}, {"model": "auth.permission", "pk": 44, "fields": {"name": "Can view image", "content_type": 11, "codename": "view_image"}}, {"model": "auth.permission", "pk": 45, "fields": {"name": "Can add instance", "content_type": 12, "codename": "add_instance"}}, {"model": "auth.permission", "pk": 46, "fields": {"name": "Can change instance", "content_type": 12, "codename": "change_instance"}}, {"model": "auth.permission", "pk": 47, "fields": {"name": "Can delete instance", "content_type": 12, "codename": "delete_instance"}}, {"model": "auth.permission", "pk": 48, "fields": {"name": "Can view instance", "content_type": 12, "codename": "view_instance"}}, {"model": "auth.permission", "pk": 49, "fields": {"name": "Can create a new VM.", "content_type": 12, "codename": "create_instance"}}, {"model": "auth.permission", "pk": 50, "fields": {"name": "Can access the VM connection info.", "content_type": 12, "codename": "use_instance"}}, {"model": "auth.permission", "pk": 51, "fields": {"name": "Can use basic lifecycle methods of the VM.", "content_type": 12, "codename": "operate_instance"}}, {"model": "auth.permission", "pk": 52, "fields": {"name": "Can delete VM.", "content_type": 12, "codename": "administer_instance"}}, {"model": "auth.permission", "pk": 53, "fields": {"name": "Can access the graphical console of a VM.", "content_type": 12, "codename": "access_console"}}, {"model": "auth.permission", "pk": 54, "fields": {"name": "Can change resources of a VM.", "content_type": 12, "codename": "change_resources"}}, {"model": "auth.permission", "pk": 55, "fields": {"name": "Can manage access rights for the VM.", "content_type": 12, "codename": "manage_access"}}, {"model": "auth.permission", "pk": 56, "fields": {"name": "Can configure port forwards.", "content_type": 12, "codename": "config_ports"}}, {"model": "auth.permission", "pk": 57, "fields": {"name": "Can add flavor", "content_type": 13, "codename": "add_flavor"}}, {"model": "auth.permission", "pk": 58, "fields": {"name": "Can change flavor", "content_type": 13, "codename": "change_flavor"}}, {"model": "auth.permission", "pk": 59, "fields": {"name": "Can delete flavor", "content_type": 13, "codename": "delete_flavor"}}, {"model": "auth.permission", "pk": 60, "fields": {"name": "Can view flavor", "content_type": 13, "codename": "view_flavor"}}, {"model": "auth.permission", "pk": 61, "fields": {"name": "Can add lease", "content_type": 14, "codename": "add_lease"}}, {"model": "auth.permission", "pk": 62, "fields": {"name": "Can change lease", "content_type": 14, "codename": "change_lease"}}, {"model": "auth.permission", "pk": 63, "fields": {"name": "Can delete lease", "content_type": 14, "codename": "delete_lease"}}, {"model": "auth.permission", "pk": 64, "fields": {"name": "Can view lease", "content_type": 14, "codename": "view_lease"}}, {"model": "auth.permission", "pk": 65, "fields": {"name": "Can add base template", "content_type": 15, "codename": "add_basetemplate"}}, {"model": "auth.permission", "pk": 66, "fields": {"name": "Can change base template", "content_type": 15, "codename": "change_basetemplate"}}, {"model": "auth.permission", "pk": 67, "fields": {"name": "Can delete base template", "content_type": 15, "codename": "delete_basetemplate"}}, {"model": "auth.permission", "pk": 68, "fields": {"name": "Can view base template", "content_type": 15, "codename": "view_basetemplate"}}, {"model": "auth.permission", "pk": 69, "fields": {"name": "Can add disk template", "content_type": 16, "codename": "add_disktemplate"}}, {"model": "auth.permission", "pk": 70, "fields": {"name": "Can change disk template", "content_type": 16, "codename": "change_disktemplate"}}, {"model": "auth.permission", "pk": 71, "fields": {"name": "Can delete disk template", "content_type": 16, "codename": "delete_disktemplate"}}, {"model": "auth.permission", "pk": 72, "fields": {"name": "Can view disk template", "content_type": 16, "codename": "view_disktemplate"}}, {"model": "auth.permission", "pk": 73, "fields": {"name": "Can add image template", "content_type": 17, "codename": "add_imagetemplate"}}, {"model": "auth.permission", "pk": 74, "fields": {"name": "Can change image template", "content_type": 17, "codename": "change_imagetemplate"}}, {"model": "auth.permission", "pk": 75, "fields": {"name": "Can delete image template", "content_type": 17, "codename": "delete_imagetemplate"}}, {"model": "auth.permission", "pk": 76, "fields": {"name": "Can view image template", "content_type": 17, "codename": "view_imagetemplate"}}, {"model": "auth.user", "pk": 1, "fields": {"password": "!BkKh1MBK4GmVoZLeBl2gweVrtiyarSrzocRHRQG8", "last_login": null, "is_superuser": false, "username": "AnonymousUser", "first_name": "", "last_name": "", "email": "", "is_staff": false, "is_active": true, "date_joined": "2019-08-07T12:48:40.789Z", "groups": [], "user_permissions": []}}, {"model": "auth.user", "pk": 4, "fields": {"password": "pbkdf2_sha256$150000$X00LpQFVuMGm$WaLxx98j+zyF4fG1b7YPCghE6eCDCyM+2NvkUEJbvIM=", "last_login": "2019-08-08T12:10:15.298Z", "is_superuser": true, "username": "admin", "first_name": "", "last_name": "", "email": "admin@recircle.bme.hu", "is_staff": true, "is_active": true, "date_joined": "2019-08-08T12:06:33.109Z", "groups": [], "user_permissions": []}}, {"model": "guardian.userobjectpermission", "pk": 1, "fields": {"permission": 47, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 2, "fields": {"permission": 54, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 3, "fields": {"permission": 56, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 4, "fields": {"permission": 46, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 5, "fields": {"permission": 51, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 6, "fields": {"permission": 50, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 7, "fields": {"permission": 55, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 8, "fields": {"permission": 53, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 9, "fields": {"permission": 48, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 10, "fields": {"permission": 52, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 11, "fields": {"permission": 45, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "guardian.userobjectpermission", "pk": 12, "fields": {"permission": 49, "content_type": 12, "object_pk": "1", "user": 4}}, {"model": "image.image", "pk": 1, "fields": {"name": "Ubuntu 18.04", "description": "", "remote_id": "9520a513-6e2d-4059-80c6-1afd1fbfe24d", "created_at": "2019-08-08T12:05:31.288Z", "uploaded_by_user": true, "created_by": 4}}, {"model": "instance.instance", "pk": 1, "fields": {"name": "Uborka", "remote_id": "92d7264a-1292-4c4e-a8d8-4dcef086d7c6", "description": "Uborka", "access_method": "ssh", "system": "ubuntu", "password": "12345", "time_of_suspend": "2019-08-09T02:04:12.768Z", "time_of_delete": "2019-08-09T02:04:12.768Z", "deleted": false, "template": 1, "owner": 4, "flavor": 1, "lease": 1, "disks": [1]}}, {"model": "template.basetemplate", "pk": 1, "fields": {"name": "Uborka template", "description": "", "created_at": "2019-08-08T12:09:20.290Z", "created_by": 4, "flavor": 1, "lease": 1, "network_id": null}}, {"model": "template.imagetemplate", "pk": 1, "fields": {"image": 1, "type": "U"}}, {"model": "admin.logentry", "pk": 5, "fields": {"action_time": "2019-08-08T12:07:02.809Z", "user": 4, "content_type": 4, "object_id": "2", "object_repr": "adam", "action_flag": 3, "change_message": ""}}, {"model": "admin.logentry", "pk": 6, "fields": {"action_time": "2019-08-08T12:07:02.815Z", "user": 4, "content_type": 4, "object_id": "3", "object_repr": "adam2", "action_flag": 3, "change_message": ""}}, {"model": "admin.logentry", "pk": 7, "fields": {"action_time": "2019-08-08T12:07:33.903Z", "user": 4, "content_type": 11, "object_id": "1", "object_repr": "Image object (1)", "action_flag": 2, "change_message": "[{\"changed\": {\"fields\": [\"created_by\"]}}]"}}, {"model": "admin.logentry", "pk": 8, "fields": {"action_time": "2019-08-08T12:07:57.845Z", "user": 4, "content_type": 4, "object_id": "2", "object_repr": "adam", "action_flag": 3, "change_message": ""}}, {"model": "admin.logentry", "pk": 9, "fields": {"action_time": "2019-08-08T12:07:57.852Z", "user": 4, "content_type": 4, "object_id": "3", "object_repr": "adam2", "action_flag": 3, "change_message": ""}}, {"model": "admin.logentry", "pk": 10, "fields": {"action_time": "2019-08-08T12:09:20.292Z", "user": 4, "content_type": 17, "object_id": "1", "object_repr": "ImageTemplate object (1)", "action_flag": 1, "change_message": "[{\"added\": {}}]"}}, {"model": "admin.logentry", "pk": 11, "fields": {"action_time": "2019-08-08T12:10:52.773Z", "user": 4, "content_type": 12, "object_id": "1", "object_repr": "Instance object (1)", "action_flag": 1, "change_message": "[{\"added\": {}}]"}}]
\ No newline at end of file
# Generated by Django 2.2.4 on 2019-08-08 11:37
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('instance', '0010_instance_template'),
]
operations = [
migrations.AlterModelOptions(
name='instance',
options={'permissions': (('create_instance', 'Can create a new VM.'), ('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.'))},
),
]
# Generated by Django 2.2.4 on 2019-08-29 07:54
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('instance', '0011_auto_20190808_1137'),
]
operations = [
migrations.AlterModelOptions(
name='instance',
options={'default_permissions': (), 'permissions': (('create_instance', 'Can create a new VM.'), ('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.'))},
),
]
# 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.'))},
),
]
......@@ -5,8 +5,8 @@ from django.utils import timezone
from datetime import timedelta
from image.models import Disk
from interface_openstack.implementation.vm.instance import (
OSVirtualMachineManager
)
OSVirtualMachineManager
)
import logging
logger = logging.getLogger(__name__)
......@@ -45,8 +45,8 @@ class Flavor(models.Model):
name = models.CharField(blank=True, max_length=100)
description = models.CharField(blank=True, max_length=200)
remote_id = models.CharField(
max_length=100, help_text="ID of the instance on the backend"
)
max_length=100, help_text="ID of the instance on the backend"
)
ram = models.IntegerField(blank=True, null=True)
vcpu = models.IntegerField(blank=True, null=True)
initial_disk = models.IntegerField(blank=True, null=True)
......@@ -82,6 +82,20 @@ class Instance(models.Model):
"""
from template.models import ImageTemplate
class Meta:
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.'),
)
name = models.CharField(max_length=100,
help_text="Human readable name of instance")
......@@ -167,10 +181,20 @@ class Instance(models.Model):
lease = self.lease
return (
timezone.now() + timedelta(
seconds=lease.suspend_interval_in_sec),
seconds=lease.suspend_interval_in_sec),
timezone.now() + timedelta(
seconds=lease.delete_interval_in_sec)
)
seconds=lease.delete_interval_in_sec)
)
def renew(self, lease=None):
"""Renew virtual machine, if a new lease is provided it changes it as well.
"""
if lease is None:
lease = self.lease
else:
self.lease = lease
self.time_of_suspend, self.time_of_delete = self.get_renew_times(lease)
self.save()
def delete(self):
try:
......@@ -192,5 +216,13 @@ class Instance(models.Model):
@classmethod
def generate_password(self):
return User.objects.make_random_password(
allowed_chars='abcdefghijklmnopqrstuvwx'
'ABCDEFGHIJKLMNOPQRSTUVWX123456789')
allowed_chars='abcdefghijklmnopqrstuvwx'
'ABCDEFGHIJKLMNOPQRSTUVWX123456789')
def change_name(self, new_name):
self.name = new_name
self.save()
def change_description(self, new_description):
self.description = new_description
self.save()
......@@ -9,9 +9,46 @@ from template.serializers import InstanceFromTemplateSerializer
from instance.models import Instance, Flavor, Lease
from template.models import ImageTemplate
from template.serializers import ImageTemplateModelSerializer
class InstanceViewSet(ViewSet):
from authorization.mixins import AuthorizationMixin
authorization = {
"list": {"filter": ["use_instance"]},
"create": {"model": ["instance.create_instance"]},
"retrieve": {"object": ["use_instance"]},
"update": {"object": ["use_instance"]},
"destroy": {"object": ["administer_instance"]},
"template": {"model": ["create_template_from_instance"],
"object": ["use_instance"]},
"start": {"object": ["operate_instance"]},
"stop": {"object": ["operate_instance"]},
"suspend": {"object": ["operate_instance"]},
"wake_up": {"object": ["operate_instance"]},
"reset": {"object": ["operate_instance"]},
"reboot": {"object": ["operate_instance"]},
}
update_actions = [
"change_name",
"change_description",
"renew",
"change_lease",
"change_flavor",
"attach_disk",
"resize_disk",
"add_permission",
"remove_permission",
"open_port",
"close_port",
"add_network",
"remove_network",
"new_password",
]
class InstanceViewSet(AuthorizationMixin, ViewSet):
authorization = authorization
def get_object(self, pk):
try:
......@@ -20,10 +57,14 @@ class InstanceViewSet(ViewSet):
raise Http404
def list(self, request):
instances = Instance.objects.all()
instances = self.get_objects_with_perms(request.user, "list", Instance)
return Response(InstanceSerializer(instances, many=True).data)
def create(self, request):
if not self.has_perms_for_model(request.user, 'create'):
return Response({"error": "No permission to create Virtual Machine."},
status=status.HTTP_401_UNAUTHORIZED)
data = request.data
template = ImageTemplate.objects.get(pk=data["template"])
......@@ -50,6 +91,10 @@ class InstanceViewSet(ViewSet):
def retrieve(self, request, pk):
instance = self.get_object(pk)
if not self.has_perms_for_object(request.user, 'retrieve', instance):
return Response({"error": "No permission to access the Virtual Machine."},
status=status.HTTP_401_UNAUTHORIZED)
instanceDict = InstanceSerializer(instance).data
remoteInstance = instance.get_remote_instance()
remoteInstanceDict = remoteInstance.__dict__
......@@ -59,21 +104,67 @@ class InstanceViewSet(ViewSet):
return Response(merged_dict)
def update(self, request, pk, format=None):
instance = self.get_object(pk)
serializer = InstanceSerializer(instance, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
if request.data["action"] in update_actions:
instance = self.get_object(pk)
if not self.has_perms_for_object(request.user, 'update', instance):
return Response({"error": "No permission to access the Virtual Machine."},
status=status.HTTP_401_UNAUTHORIZED)
action = request.data["action"]
if action == "change_name":
instance.change_name(request.data["name"])
elif action == "change_description":
instance.change_description(request.data["description"])
elif action == "renew":
instance.renew()
elif action == "change_lease":
lease = Lease.objects.get(pk=request.data["lease"])
instance.renew(lease)
elif action == "change_flavor":
pass
elif action == "attach_disk":
pass
elif action == "resize_disk":
pass
elif action == "add_permission":
pass
elif action == "remove_permission":
pass
elif action == "open_port":
pass
elif action == "close_port":
pass
elif action == "add_network":
pass
elif action == "remove_network":
pass
elif action == "new_password":
pass
instanceDict = InstanceSerializer(instance).data
remoteInstance = instance.get_remote_instance()
remoteInstanceDict = remoteInstance.__dict__
merged_dict = {"db": instanceDict, "openstack": remoteInstanceDict}
return Response(merged_dict)
else:
return Response({"error": "Unknown update action."}, status=status.HTTP_400_BAD_REQUEST)
def destroy(self, request, pk, format=None):
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()
return Response(status=status.HTTP_204_NO_CONTENT)
@action(detail=True, methods=["post"])
def template(self, request, 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.is_valid(raise_exception=True)
data = serializer.validated_data
......@@ -87,8 +178,10 @@ class InstanceViewSet(ViewSet):
@action(detail=True, methods=["POST"])
def actions(self, request, 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"])
return Response(success)
......
......@@ -41,6 +41,7 @@ INSTALLED_APPS = [
"djoser",
"rest_framework_swagger",
"corsheaders",
"guardian",
"django_nose",
]
......@@ -49,6 +50,7 @@ LOCAL_APPS = [
"instance",
"storage",
"template",
"authorization",
]
INSTALLED_APPS += LOCAL_APPS
......@@ -112,6 +114,7 @@ REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema' # needed for swagger
}
# Internationalization
......@@ -230,3 +233,10 @@ LOGGING = {
for i in LOCAL_APPS:
LOGGING['loggers'][i] = {'handlers': ['console'], 'level': 'DEBUG'}
# Configure django-guardian for the authorization
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend', # this is default
'guardian.backends.ObjectPermissionBackend',
)
......@@ -12,5 +12,8 @@ ADMIN_ENABLED = True
ALLOWED_HOSTS = ['*']
AUTH_PASSWORD_VALIDATORS = []
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
NOSE_ARGS = LOCAL_APPS
\ No newline at end of file
NOSE_ARGS = LOCAL_APPS
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