Commit 41f8460e by Szabolcs Gelencser

Fix user assignment, use group-compatible listing

parent 1e44ca63
...@@ -19,32 +19,23 @@ ...@@ -19,32 +19,23 @@
{# title="{{ i.user.username }}">#} {# title="{{ i.user.username }}">#}
{# {% include "dashboard/_display-name.html" with user=i.user show_org=True %}#} {# {% include "dashboard/_display-name.html" with user=i.user show_org=True %}#}
{# </a>#} {# </a>#}
{{ member.username }} {{ member.name }}
</td> </td>
<td> <td>
<input type="checkbox" name="remove-u-{{ member.member_id }}" title="{% trans "Remove" %}"/> <input type="checkbox" name="remove-u-{{ member.project_id }}" title="{% trans "Remove" %}"/>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
{% for i in acl.groups %} {% for member in shared_with_groups %}
<tr> <tr>
<td><i class="fa fa-group"></i></td> <td><i class="fa fa-group"></i></td>
<td> <td>
<a href="{% url "dashboard.views.group-detail" pk=i.group.pk %}"> {# <a href="{% url "dashboard.views.group-detail" pk=i.group.pk %}">#}
{{i.group}} {{ member.name }}
</a> {# </a>#}
</td>
<td>
<select class="form-control" name="perm-g-{{i.group.id}}{% if i.level not in acl.allowed_levels %} disabled{% endif %}">
{% for id, name in acl.levels %}
<option{%if id == i.level%} selected="selected"{%endif%}
{% if id not in acl.allowed_levels %} disabled{% endif %}
value="{{id}}">{{name}}</option>
{% endfor %}
</select>
</td> </td>
<td> <td>
<input type="checkbox" name="remove-g-{{i.group.id}}" title="{% trans "Remove" %}"/> <input type="checkbox" name="remove-g-{{ member.id }}" title="{% trans "Remove" %}"/>
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
......
...@@ -44,6 +44,7 @@ from django.views.generic.edit import BaseUpdateView, ModelFormMixin, FormView ...@@ -44,6 +44,7 @@ from django.views.generic.edit import BaseUpdateView, ModelFormMixin, FormView
from django_tables2 import SingleTableView from django_tables2 import SingleTableView
from keystoneauth1 import session from keystoneauth1 import session
from keystoneauth1.identity import v3 from keystoneauth1.identity import v3
from vm.models.instance import TemplateUserMember, TemplateGroupMember
from openstack_auth.utils import fix_auth_url_version from openstack_auth.utils import fix_auth_url_version
from vm.models import ( from vm.models import (
...@@ -340,49 +341,6 @@ class TemplateDetail(LoginRequiredMixin, GraphMixin, SuccessMessageMixin, Update ...@@ -340,49 +341,6 @@ class TemplateDetail(LoginRequiredMixin, GraphMixin, SuccessMessageMixin, Update
else: else:
return super(TemplateDetail, self).get(request, *args, **kwargs) return super(TemplateDetail, self).get(request, *args, **kwargs)
def __get_glance_admin_client(self, request):
from keystoneauth1 import session
from glanceclient import Client
auth = v3.Password(
auth_url=fix_auth_url_version(settings.OPENSTACK_KEYSTONE_URL),
user_id=settings.OPENSTACK_CIRCLE_USERID,
password=settings.OPENSTACK_CIRCLE_PASSWORD,
project_id=request.user.tenant_id,
)
session = session.Session(auth=auth, verify=False)
return Client('2', session=session)
def __get_members_shared_with(self):
template = self.get_object()
glance = self.__get_glance_admin_client(self.request)
members_generator = glance.image_members.list(template.image_id)
return [m for m in members_generator]
def __get_project_client(self, project_id):
from keystoneclient.v3 import client
auth = v3.Password(
auth_url=fix_auth_url_version(settings.OPENSTACK_KEYSTONE_URL),
user_id=settings.OPENSTACK_CIRCLE_USERID,
password=settings.OPENSTACK_CIRCLE_PASSWORD,
project_id=project_id,
)
sess = session.Session(auth=auth, verify=False)
return client.Client(session=sess, interface='public')
def __get_username_for(self, project_id):
client = self.__get_project_client(project_id)
project = client.projects.get(project_id)
return project.name # as username = project's name
def __get_users_shared_with(self):
members = self.__get_members_shared_with()
for m in members:
m['username'] = self.__get_username_for(m.member_id)
return members
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
template = self.get_object() template = self.get_object()
openstack_api.glance.image_update(self.request, template.image_id, visibility="shared") openstack_api.glance.image_update(self.request, template.image_id, visibility="shared")
...@@ -391,7 +349,10 @@ class TemplateDetail(LoginRequiredMixin, GraphMixin, SuccessMessageMixin, Update ...@@ -391,7 +349,10 @@ class TemplateDetail(LoginRequiredMixin, GraphMixin, SuccessMessageMixin, Update
# template, self.request.user, 'dashboard.views.template-acl') # template, self.request.user, 'dashboard.views.template-acl')
context['manage_access_url'] = reverse_lazy('dashboard.views.template-acl', context['manage_access_url'] = reverse_lazy('dashboard.views.template-acl',
kwargs={'pk': template.id}) kwargs={'pk': template.id})
context['shared_with_users'] = self.__get_users_shared_with() context['shared_with_users'] = TemplateUserMember.objects.filter(
instancetemplate__image_id=template.image_id)
context['shared_with_groups'] = TemplateGroupMember.objects.filter(
instancetemplate__image_id=template.image_id)
# context['disks'] = template.disks.all() # context['disks'] = template.disks.all()
context['is_owner'] = template.owner_id == self.request.user.id context['is_owner'] = template.owner_id == self.request.user.id
context['aclform'] = AclUserOrGroupAddForm() context['aclform'] = AclUserOrGroupAddForm()
......
...@@ -29,6 +29,7 @@ from django.contrib.auth.mixins import AccessMixin ...@@ -29,6 +29,7 @@ from django.contrib.auth.mixins import AccessMixin
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.db import IntegrityError
from django.db.models import Q, Count, Sum from django.db.models import Q, Count, Sum
from django.http import ( from django.http import (
HttpResponse, Http404, HttpResponseRedirect, JsonResponse HttpResponse, Http404, HttpResponseRedirect, JsonResponse
...@@ -44,7 +45,7 @@ from django.views.decorators.debug import sensitive_post_parameters ...@@ -44,7 +45,7 @@ from django.views.decorators.debug import sensitive_post_parameters
from django.views.generic import DetailView, View, DeleteView, FormView from django.views.generic import DetailView, View, DeleteView, FormView
from django.views.generic.detail import SingleObjectMixin from django.views.generic.detail import SingleObjectMixin
from keystoneauth1.identity import v3 from keystoneauth1.identity import v3
from vm.models.instance import TemplateGroupMember from vm.models.instance import TemplateGroupMember, TemplateUserMember
from openstack_auth.utils import fix_auth_url_version from openstack_auth.utils import fix_auth_url_version
from vm.models import Instance from vm.models import Instance
...@@ -484,8 +485,15 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin): ...@@ -484,8 +485,15 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
msg = _("Already shared with group %s" % new_group_name) msg = _("Already shared with group %s" % new_group_name)
messages.warning(self.request, msg) messages.warning(self.request, msg)
else: else:
template.groups.get_or_create(group_id=new_group.id) try:
group = TemplateGroupMember(group_id=new_group.id, name=new_group_name)
group.save()
except IntegrityError:
group = TemplateGroupMember.objects.get(group_id=new_group.id)
template.groups.add(group)
template.save() template.save()
msg = _("Successfully shared with group %s" % new_group_name)
messages.success(self.request, msg)
def __handle_user_assignment(self): def __handle_user_assignment(self):
glance = self.__get_glance_admin_client(self.request.user.tenant_id) glance = self.__get_glance_admin_client(self.request.user.tenant_id)
...@@ -502,6 +510,13 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin): ...@@ -502,6 +510,13 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
elif project_id_of_user is not None: elif project_id_of_user is not None:
glance.image_members.create(template.image_id, project_id_of_user) glance.image_members.create(template.image_id, project_id_of_user)
self.__accept_membership(project_id_of_user) self.__accept_membership(project_id_of_user)
try:
user = TemplateUserMember(project_id=project_id_of_user, name=new_template_user)
user.save()
except IntegrityError:
user = TemplateUserMember.objects.get(project_id=project_id_of_user)
template.users.add(user)
template.save()
msg = _("Successfully shared with %s" % new_template_user) msg = _("Successfully shared with %s" % new_template_user)
messages.success(self.request, msg) messages.success(self.request, msg)
else: else:
...@@ -538,12 +553,23 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin): ...@@ -538,12 +553,23 @@ class AclUpdateView(LoginRequiredMixin, View, SingleObjectMixin):
template = self.get_object() template = self.get_object()
glance = self.__get_glance_admin_client(self.request.user.tenant_id) glance = self.__get_glance_admin_client(self.request.user.tenant_id)
glance.image_members.delete(template.image_id, member_id) glance.image_members.delete(template.image_id, member_id)
user = TemplateUserMember.objects.get(project_id=member_id)
template.users.remove(user)
template.save()
def __remove_group(self, member_id):
template = self.get_object()
template.groups.remove(member_id)
template.save()
def __handle_removes(self): def __handle_removes(self):
removes = self.__get_removes() removes = self.__get_removes()
for member_id in removes['u']: for member_id in removes['u']:
self.__remove_user(member_id) self.__remove_user(member_id)
messages.success(self.request, _("Successfully removed user")) messages.success(self.request, _("Successfully removed user"))
for member_id in removes['g']:
self.__remove_group(member_id)
messages.success(self.request, _("Successfully removed group"))
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
template = self.get_object() template = self.get_object()
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-31 16:05
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('vm', '0017_auto_20180531_1455'),
]
operations = [
migrations.AddField(
model_name='templategroupmember',
name='name',
field=models.CharField(default='asd', max_length=100, unique=True),
preserve_default=False,
),
migrations.AddField(
model_name='templateusermember',
name='name',
field=models.CharField(default='qwe', max_length=100, unique=True),
preserve_default=False,
),
]
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2018-05-31 16:09
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('vm', '0018_auto_20180531_1805'),
]
operations = [
migrations.RenameField(
model_name='templateusermember',
old_name='user_id',
new_name='project_id',
),
]
...@@ -120,7 +120,8 @@ class VirtualMachineDescModel(BaseResourceConfigModel): ...@@ -120,7 +120,8 @@ class VirtualMachineDescModel(BaseResourceConfigModel):
class TemplateUserMember(Model): class TemplateUserMember(Model):
user_id = CharField(blank=False, max_length=100, unique=True) name = CharField(blank=False, max_length=100, unique=True)
project_id = CharField(blank=False, max_length=100, unique=True)
class Meta: class Meta:
app_label = 'vm' app_label = 'vm'
...@@ -128,6 +129,7 @@ class TemplateUserMember(Model): ...@@ -128,6 +129,7 @@ class TemplateUserMember(Model):
class TemplateGroupMember(Model): class TemplateGroupMember(Model):
name = CharField(blank=False, max_length=100, unique=True)
group_id = CharField(blank=False, max_length=100, unique=True) group_id = CharField(blank=False, max_length=100, unique=True)
class Meta: class Meta:
......
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