def home(request, slice_id): """Show buttons to download and upload rspecs.""" slice = get_object_or_404(Slice, pk=slice_id) info = GENISliceInfo.objects.get(slice=slice) slice_urn = info.slice_urn must_have_permission(request.user, slice.project, "can_edit_slices") if request.method == "POST": form = UploadRSpecForm(request.POST, request.FILES) if form.is_valid(): # parse the rspec rspec = form.files["rspec"].read() gapi.CreateSliver(slice_urn, rspec, request.user) DatedMessage.objects.post_message_to_user( "Successfully uploaded RSpec.", request.user, msg_type=DatedMessage.TYPE_SUCCESS) return HttpResponseRedirect(request.path) else: form = UploadRSpecForm() return simple.direct_to_template( request, template=TEMPLATE_PATH + "/home.html", extra_context={ "form": form, "slice_urn": slice_urn, "slice": slice, }, )
def remove_from_project(self, project, next): """ Similar to L{add_to_project} but does the reverse, deleting the permission from the project using:: from expedient.common.permissions.shortcuts import \ delete_permission delete_permission("can_use_aggregate", self.as_leaf_class(), project) and then redirecting to C{next}. Additionally, if not overridden, this function stops all slices in the project before removing the aggregate. Subclasses should also stop slices. """ must_have_permission("user", self.as_leaf_class(), "can_use_aggregate") prefix = self.__class__.get_url_name_prefix() try: return reverse("%s_aggregate_project_remove" % prefix, kwargs={ 'agg_id': self.id, 'proj_id': project.id }) + "?next=%s" % next except NoReverseMatch: # Stop all the slices in the project for this aggregate. for slice in project.slice_set.all(): try: self.as_leaf_class().stop_slice(slice) except: pass delete_permission("can_use_aggregate", self.as_leaf_class(), project) return next
def user_cert_upload(request, user_id): """Upload a key and certificate""" user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_change_user_cert") if request.method == "POST": form = UploadCertForm(data=request.POST, files=request.FILES) if form.is_valid(): form.save(user) DatedMessage.objects.post_message_to_user( "Successfully uploaded GCF certificate and key for user %s.", user=request.user, msg_type=DatedMessage.TYPE_SUCCESS) return HttpResponseRedirect( reverse("gcf_cert_manage", args=[user_id]) ) else: form = UploadCertForm() return simple.direct_to_template( request, template="user_cert_upload.html", extra_context={ "curr_user": user, "form": form, } )
def delete(request, role_id): """Delete a role""" role = get_object_or_404(ProjectRole, pk=role_id) project = role.project # require permission to proceed must_have_permission(request.user, project, "can_edit_roles") if role.name == "owner" or role.name == "researcher": return simple.direct_to_template( request, template=TEMPLATE_PATH+"/delete_default.html", extra_context={"role": role}) if request.method == "POST": role.delete() return HttpResponseRedirect( reverse("project_detail", args=[project.id])) return simple.direct_to_template( request, template=TEMPLATE_PATH+"/delete.html", extra_context={ "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % role.project.name, reverse("project_detail", args=[role.project.id])), ("Delete Role %s" % role.name, request.path), ), "role": role}, )
def user_cert_manage(request, user_id): """Allow the user to download/regenerate/upload a GCF certificate. @param request: the request object @param user_id: the id of the user whose certificate we are managing. """ user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_change_user_cert") cert_fname = get_user_cert_fname(user) if not os.access(cert_fname, os.F_OK): cert = None else: cert = read_cert_from_file(cert_fname) return simple.direct_to_template( request, template="user_cert_manage.html", extra_context={ "curr_user": user, "cert": cert, }, )
def user_cert_manage(request, user_id): """Allow the user to download/regenerate/upload a GCF certificate. @param request: the request object @param user_id: the id of the user whose certificate we are managing. """ user = get_object_or_404(User, pk=user_id) user_profile = UserProfile.get_or_create_profile(request.user) user_cert = user_profile.certificate private_ssh_key_exists = len(user_profile.private_ssh_key) > 0 public_ssh_key_exists = len(user_profile.public_ssh_key) > 0 must_have_permission(request.user, user, "can_change_user_cert") cert_fname = get_user_cert_fname(user) if not os.access(cert_fname, os.F_OK): cert = None else: cert = read_cert_from_string(user_cert) return simple.direct_to_template( request, template=TEMPLATE_PATH + "/user_cert_manage.html", extra_context={ "curr_user": user, "cert": cert, "private_ssh_key_exists": private_ssh_key_exists, "public_ssh_key_exists": public_ssh_key_exists }, )
def user_cert_manage(request, user_id): """Allow the user to download/regenerate/upload a GCF certificate. @param request: the request object @param user_id: the id of the user whose certificate we are managing. """ user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_change_user_cert") cert_fname = get_user_cert_fname(user) if not os.access(cert_fname, os.F_OK): cert = None else: cert = read_cert_from_file(cert_fname) return simple.direct_to_template( request, template=TEMPLATE_PATH + "/user_cert_manage.html", extra_context={ "curr_user": user, "cert": cert, }, )
def remove_controller_from_slice(request, agg_id, slice_id): """Perform the actual remove_controller_from_slice request.""" aggregate = get_object_or_404(OpenFlowAggregate, id=agg_id) slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, aggregate, "can_use_aggregate") must_have_permission(slice.project, aggregate, "can_use_aggregate") # Check if there's info already and delete it. error = "" try: OpenFlowSliceInfo.objects.get(slice=slice).delete() # Also, stop slice (any started slice must have a controller) if slice.started: slice.stop(request.user) except OpenFlowSliceInfo.DoesNotExist: error = "OpentFlow plug-in: could not delete controller from slice. Details: no controller was already there" except Exception as e: error = "OpentFlow plug-in: could not delete controller from slice: %s. Details: %s" % (str(slice.id). str(e)) print error DatedMessage.objects.post_message_to_user( error, request.user, msg_type=DatedMessage.TYPE_ERROR, ) # Get back to slice detail page return HttpResponseRedirect(reverse("slice_detail", args=[slice_id]))
def user_cert_generate(request, user_id): """Create a new user certificate after confirmation. @param request: the request object @param user_id: the id of the user whose certificate we are generating. """ user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_change_user_cert") cert_fname = get_user_cert_fname(user) key_fname = get_user_key_fname(user) urn = get_user_urn(user.username) if request.method == "POST": create_x509_cert(urn, cert_fname, key_fname) DatedMessage.objects.post_message_to_user( "GCF Certificate for user %s successfully created." % user.username, user=request.user, msg_type=DatedMessage.TYPE_SUCCESS) return HttpResponseRedirect(reverse(user_cert_manage, args=[user.id])) return simple.direct_to_template( request, template="user_cert_generate.html", extra_context={ "curr_user": user, }, )
def delete(request, role_id): """Delete a role""" role = get_object_or_404(ProjectRole, pk=role_id) project = role.project # require permission to proceed must_have_permission(request.user, project, "can_edit_roles") if role.name == "owner" or role.name == "researcher": return simple.direct_to_template(request, template=TEMPLATE_PATH + "/delete_default.html", extra_context={"role": role}) if request.method == "POST": role.delete() return HttpResponseRedirect( reverse("project_detail", args=[project.id])) return simple.direct_to_template( request, template=TEMPLATE_PATH + "/delete.html", extra_context={ "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % role.project.name, reverse("project_detail", args=[role.project.id])), ("Delete Role %s" % role.name, request.path), ), "role": role }, )
def update(request, proj_id, iframe=False): '''Update information about a project''' project = get_object_or_404(Project, id=proj_id) must_have_permission(request.user, project, "can_edit_project") def redirect(instance): if iframe: return reverse("project_list") else: return reverse("project_detail", args=[instance.id]) return generic_crud( request, proj_id, model=Project, form_class=ProjectCreateForm, template=TEMPLATE_PATH + "/create_update.html", redirect=redirect, template_object_name="project", extra_context={ "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % project.name, reverse("project_detail", args=[project.id])), ("Update Info", request.path), ), }, success_msg=lambda instance: "Successfully updated project %s." % instance.name, )
def user_cert_generate(request, user_id): """Create a new user certificate after confirmation. @param request: the request object @param user_id: the id of the user whose certificate we are generating. """ user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_change_user_cert") cert_fname = get_user_cert_fname(user) key_fname = get_user_key_fname(user) urn = get_user_urn(user.username) if request.method == "POST": create_x509_cert(urn, cert_fname, key_fname) DatedMessage.objects.post_message_to_user( "GCF Certificate for user %s successfully created." % user.username, user=request.user, msg_type=DatedMessage.TYPE_SUCCESS) return HttpResponseRedirect(reverse(user_cert_manage, args=[user.id])) return simple.direct_to_template( request, template=TEMPLATE_PATH + "/user_cert_generate.html", extra_context={ "curr_user": user, }, )
def remove_aggregate(request, slice_id, agg_id): slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_edit_slices") aggregate = get_object_or_404(Aggregate, id=agg_id, id__in=slice.aggregates.values_list( "id", flat=True)).as_leaf_class() if request.method == "POST": try: return HttpResponseRedirect( aggregate.remove_from_slice( slice, reverse("slice_detail", args=[slice_id]))) except MultipleObjectsReturned as e: DatedMessage.objects.post_message_to_user( str(e), request.user, msg_type=DatedMessage.TYPE_ERROR) except: pass # If any error occurs, redirect to slice detail page return HttpResponseRedirect(reverse('slice_detail', args=[slice_id])) else: return HttpResponseNotAllowed(["POST"])
def remove_from_project(self, project, next): """ Similar to L{add_to_project} but does the reverse, deleting the permission from the project using:: from expedient.common.permissions.shortcuts import \ delete_permission delete_permission("can_use_aggregate", self.as_leaf_class(), project) and then redirecting to C{next}. Additionally, if not overridden, this function stops all slices in the project before removing the aggregate. Subclasses should also stop slices. """ must_have_permission("user", self.as_leaf_class(), "can_use_aggregate") prefix = self.__class__.get_url_name_prefix() try: return reverse("%s_aggregate_project_remove" % prefix, kwargs={'agg_id': self.id, 'proj_id': project.id})+"?next=%s" % next except NoReverseMatch: # Stop all the slices in the project for this aggregate. for slice in project.slice_set.all(): try: self.as_leaf_class().stop_slice(slice) except: pass # Carolina: remove permision for aggregate in every slice inside the project self.remove_from_slice(slice, next) delete_permission("can_use_aggregate", self.as_leaf_class(), project) return next
def user_cert_upload(request, user_id): """Upload a key and certificate""" user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_change_user_cert") if request.method == "POST": form = UploadCertForm(data=request.POST, files=request.FILES) if form.is_valid(): form.save(user) DatedMessage.objects.post_message_to_user( "Successfully uploaded GCF certificate and key for user %s.", user=request.user, msg_type=DatedMessage.TYPE_SUCCESS) return HttpResponseRedirect( reverse("gcf_cert_manage", args=[user_id])) else: form = UploadCertForm() return simple.direct_to_template(request, template=TEMPLATE_PATH + "/user_cert_upload.html", extra_context={ "curr_user": user, "form": form, })
def home(request, slice_id): """Show buttons to download and upload rspecs.""" slice = get_object_or_404(Slice, pk=slice_id) info = GENISliceInfo.objects.get(slice=slice) slice_urn = info.slice_urn must_have_permission( request.user, slice.project, "can_edit_slices") if request.method == "POST": form = UploadRSpecForm(request.POST, request.FILES) if form.is_valid(): # parse the rspec rspec = form.files["rspec"].read() gapi.CreateSliver(slice_urn, rspec, request.user) DatedMessage.objects.post_message_to_user( "Successfully uploaded RSpec.", request.user, msg_type=DatedMessage.TYPE_SUCCESS) return HttpResponseRedirect(request.path) else: form = UploadRSpecForm() return simple.direct_to_template( request, template=TEMPLATE_PATH+"/home.html", extra_context={ "form": form, "slice_urn": slice_urn, "slice": slice, }, )
def stop(request, slice_id): '''Stop the slice on POST''' slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_stop_slices") if request.method == "POST": try: slice.stop(request.user) except Exception as e: import traceback traceback.print_exc() print e DatedMessage.objects.post_message_to_user( "Error stopping slice %s: %s" % (slice.name, parseFVexception(e)), user=request.user, msg_type=DatedMessage.TYPE_ERROR) else: DatedMessage.objects.post_message_to_user( "Successfully stopped slice %s" % slice.name, request.user, msg_type=DatedMessage.TYPE_SUCCESS) return HttpResponseRedirect(reverse("slice_detail", args=[slice_id])) else: return HttpResponseNotAllowed(["POST"])
def create(request, proj_id): """Create a new role for a project.""" project = get_object_or_404(Project, pk=proj_id) # require permission to proceed must_have_permission(request.user, project, "can_create_roles") obj_permissions = ObjectPermission.objects.filter_from_instance(project) project_url = reverse("project_detail", args=[project.id]) def pre_save(instance, created): instance.project = project return generic_crud(request, obj_id=None, model=ProjectRole, template=TEMPLATE_PATH + "/create.html", redirect=lambda instance: project_url, form_class=ProjectRoleForm, pre_save=pre_save, extra_form_params={ "obj_permissions": obj_permissions, }, extra_context={ "project": project, "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % project.name, project_url), ("Create Role", request.path), ) })
def user_cert_manage(request, user_id): """Allow the user to download/regenerate/upload a GCF certificate. @param request: the request object @param user_id: the id of the user whose certificate we are managing. """ user = get_object_or_404(User, pk=user_id) user_profile = UserProfile.get_or_create_profile(request.user) user_cert = user_profile.certificate private_ssh_key_exists = len(user_profile.private_ssh_key) > 0 public_ssh_key_exists = len(user_profile.public_ssh_key) > 0 must_have_permission(request.user, user, "can_change_user_cert") cert_fname = get_user_cert_fname(user) if not os.access(cert_fname, os.F_OK): cert = None else: cert = read_cert_from_string(user_cert) return simple.direct_to_template( request, template= TEMPLATE_PATH + "/user_cert_manage.html", extra_context={ "curr_user": user, "cert": cert, "private_ssh_key_exists" : private_ssh_key_exists, "public_ssh_key_exists": public_ssh_key_exists }, )
def update(request, role_id): """Update the permissions in the role""" role = get_object_or_404(ProjectRole, pk=role_id) # require permission to proceed must_have_permission(request.user, role.project, "can_edit_roles") permittee = Permittee.objects.get_as_permittee(request.user) initial_set = list(role.obj_permissions.values_list("pk", flat=True)) # Get the permissions that the user can delegate to others as well # as the ones that are already in the role. Obtain DISTINCT values. obj_permissions = ObjectPermission.objects.filter_from_instance( role.project).filter( Q(permissionownership__permittee=permittee, permissionownership__can_delegate=True) | Q(id__in=initial_set)).distinct() project_url = reverse("project_detail", args=[role.project.id]) # Use to update the permissions in the ProjectRole object so # users with that role are affected from the time this is updated def post_save(instance, created): from expedient.clearinghouse.roles.models import ObjectPermission new_obj_permissions_pks = [ p.pk for p in instance.obj_permissions.all() ] for permission in obj_permissions: # Add and delete permissions accordingly... try: instance.remove_permission(permission) except: pass if permission.pk in new_obj_permissions_pks: instance.add_permission(permission) return generic_crud( request, obj_id=role_id, model=ProjectRole, template=TEMPLATE_PATH + "/update.html", redirect=lambda instance: project_url, template_object_name="role", form_class=ProjectRoleForm, extra_form_params={ "obj_permissions": obj_permissions, }, extra_context={ "project": role.project, "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % role.project.name, project_url), ("Update Role %s" % role.name, request.path), ) }, post_save=post_save, )
def update(request, proj_id, iframe=False): '''Update information about a project''' project = get_object_or_404(Project, id=proj_id) must_have_permission(request.user, project, "can_edit_project") def redirect(instance): if iframe: return reverse("project_list") else: return reverse("project_detail", args=[instance.id]) return generic_crud( request, proj_id, model=Project, form_class=ProjectCreateForm, template=TEMPLATE_PATH+"/create_update.html", redirect=redirect, template_object_name="project", extra_context={ "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % project.name, reverse("project_detail", args=[project.id])), ("Update Info", request.path), ), }, success_msg = lambda instance: "Successfully updated project %s." % instance.name, )
def remove_controller_from_slice(request, agg_id, slice_id): """Perform the actual remove_controller_from_slice request.""" aggregate = get_object_or_404(OpenFlowAggregate, id=agg_id) slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, aggregate, "can_use_aggregate") must_have_permission(slice.project, aggregate, "can_use_aggregate") # Check if there's info already and delete it. error = "" try: OpenFlowSliceInfo.objects.get(slice=slice).delete() # Also, stop slice (any started slice must have a controller) if slice.started: slice.stop(request.user) except OpenFlowSliceInfo.DoesNotExist: error = "OpentFlow plug-in: could not delete controller from slice. Details: no controller was already there" except Exception as e: error = "OpentFlow plug-in: could not delete controller from slice: %s. Details: %s" % ( str(slice.id).str(e)) print error DatedMessage.objects.post_message_to_user( error, request.user, msg_type=DatedMessage.TYPE_ERROR, ) # Get back to slice detail page return HttpResponseRedirect(reverse("slice_detail", args=[slice_id]))
def create(request, proj_id): '''Create a slice''' project = get_object_or_404(Project, id=proj_id) must_have_permission(request.user, project, "can_create_slices") #<UT> user_profile = UserProfile.get_or_create_profile(request.user) user_urn = user_profile.urn user_cert = user_profile.certificate def pre_save(instance, created): instance.project = project instance.owner = request.user #Generate UUID: fixes caching problem on model default value instance.uuid = uuid.uuid4() #<UT> instance.urn = 'n/a' #import pdb; pdb.set_trace() if settings.ENABLE_CBAS: slice_urn = create_slice(owner_urn=user_urn, owner_certificate=user_cert, slice_name=instance.name, slice_desc=instance.description, slice_project_urn=str(project.urn)) if slice_urn: instance.urn = slice_urn instance.save() instance.reserved = False #use to give the can_delete_slices over the slice to the creator and the owners of the project def post_save(instance, created): give_permission_to("can_delete_slices", instance, instance.owner, giver=None, can_delegate=False) # for projectOwner in instance.project._get_owners(): # give_permission_to("can_delete_slices", instance, projectOwner, giver=None, can_delegate=False) return generic_crud( request, None, Slice, TEMPLATE_PATH + "/create_update.html", redirect=lambda instance: reverse("slice_detail", args=[instance.id]), form_class=SliceCrudForm, extra_context={ "project": project, "title": "Create slice", "cancel_url": reverse("project_detail", args=[proj_id]), }, pre_save=pre_save, post_save=post_save, success_msg=lambda instance: "Successfully created slice %s." % instance.name, )
def delete(self, *args, **kwargs): """ Override the default delete method to enforce permissions. """ must_have_permission(permittee_kw, self, delete_perm) # delete all permissions for the object ObjectPermission.objects.filter_from_instance(self).delete() super(model_func(), self).delete(*args, **kwargs)
def remove_from_project(self, project, next): """ aggregate.remove_from_project on a ResourceOrchestrator AM will get here first to check that no slice inside the project contains ResourceOrchestrator's for the given aggregate """ # Check permission because it won't always call parent method (where permission checks) must_have_permission("user", self.as_leaf_class(), "can_use_aggregate") return super(ResourceOrchestratorAggregate, self).remove_from_project(project, next)
def update(request, role_id): """Update the permissions in the role""" role = get_object_or_404(ProjectRole, pk=role_id) # require permission to proceed must_have_permission(request.user, role.project, "can_edit_roles") permittee = Permittee.objects.get_as_permittee(request.user) initial_set = list(role.obj_permissions.values_list("pk", flat=True)) # Get the permissions that the user can delegate to others as well # as the ones that are already in the role. Obtain DISTINCT values. obj_permissions = ObjectPermission.objects.filter_from_instance( role.project).filter( Q(permissionownership__permittee=permittee, permissionownership__can_delegate=True) | Q(id__in=initial_set) ).distinct() project_url = reverse("project_detail", args=[role.project.id]) # Use to update the permissions in the ProjectRole object so # users with that role are affected from the time this is updated def post_save(instance, created): from expedient.clearinghouse.roles.models import ObjectPermission new_obj_permissions_pks = [ p.pk for p in instance.obj_permissions.all() ] for permission in obj_permissions: # Add and delete permissions accordingly... try: instance.remove_permission(permission) except: pass if permission.pk in new_obj_permissions_pks: instance.add_permission(permission) return generic_crud( request, obj_id=role_id, model=ProjectRole, template=TEMPLATE_PATH+"/update.html", redirect=lambda instance: project_url, template_object_name="role", form_class=ProjectRoleForm, extra_form_params={ "obj_permissions": obj_permissions, }, extra_context={ "project": role.project, "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % role.project.name, project_url), ("Update Role %s" % role.name, request.path), ) }, post_save = post_save, )
def detail(request, slice_id): '''Show information about the slice''' slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_view_project") resource_list = [rsc.as_leaf_class() for rsc in slice.resource_set.all()] user_profile = UserProfile.get_or_create_profile(request.user) user_urn = user_profile.urn user_cert = user_profile.certificate #creds = get_slice_credentials(slice.project.urn, slice.urn, user_urn, user_cert) #print_debug_message(str(creds)) template_list_computation = [] template_list_network = [] template_list_aggregate = [] for plugin in PLUGIN_LOADER.plugin_settings: try: plugin_dict = PLUGIN_LOADER.plugin_settings.get(plugin) # Get templates according to the plugin category ('computation' or 'network') # instead of directly using "TEMPLATE_RESOURCES" settings if plugin_dict.get("general").get("resource_type") == "computation": template_list_computation.append(plugin_dict.get("paths").get("template_resources")) elif plugin_dict.get("general").get("resource_type") == "network": template_list_network.append(plugin_dict.get("paths").get("template_resources")) elif plugin_dict.get("general").get("resource_type") == "aggregate": template_list_aggregate.append(plugin_dict.get("paths").get("template_resources")) except Exception as e: print "[WARNING] Could not obtain template to add resources to slides in plugin '%s'. Details: %s" % (str(plugin), str(e)) plugin_context = TOPOLOGY_GENERATOR.load_ui_data(slice) # if not plugin_context['d3_nodes'] or not plugin_context['d3_links']: # template_list_computation = [] # template_list_network = [] extra_context={ "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % slice.project.name, reverse("project_detail", args=[slice.project.id])), ("Slice %s" % slice.name, reverse("slice_detail", args=[slice_id])), ), "resource_list": resource_list, "plugin_template_list_aggregate": template_list_aggregate, "plugin_template_list_network": template_list_network, "plugin_template_list_computation": template_list_computation, "plugins_path": PLUGIN_LOADER.plugins_path, } return list_detail.object_detail( request, Slice.objects.all(), object_id=slice_id, template_name=TEMPLATE_PATH+"/detail.html", template_object_name="slice", extra_context=dict(extra_context.items()+plugin_context.items()) )
def detail(request, slice_id): '''Show information about the slice''' slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_view_project") resource_list = [rsc.as_leaf_class() for rsc in slice.resource_set.all()] template_list_computation = [] template_list_network = [] for plugin in PLUGIN_LOADER.plugin_settings: try: plugin_dict = PLUGIN_LOADER.plugin_settings.get(plugin) # Get templates according to the plugin category ('computation' or 'network') # instead of directly using "TEMPLATE_RESOURCES" settings if plugin_dict.get("general").get( "resource_type") == "computation": template_list_computation.append( plugin_dict.get("paths").get("template_resources")) elif plugin_dict.get("general").get("resource_type") == "network": template_list_network.append( plugin_dict.get("paths").get("template_resources")) except Exception as e: print "[WARNING] Could not obtain template to add resources to slides in plugin '%s'. Details: %s" % ( str(plugin), str(e)) plugin_context = TOPOLOGY_GENERATOR.load_ui_data(slice) # if not plugin_context['d3_nodes'] or not plugin_context['d3_links']: # template_list_computation = [] # template_list_network = [] extra_context = { "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % slice.project.name, reverse("project_detail", args=[slice.project.id])), ("Slice %s" % slice.name, reverse("slice_detail", args=[slice_id])), ), "resource_list": resource_list, "plugin_template_list_network": template_list_network, "plugin_template_list_computation": template_list_computation, "plugins_path": PLUGIN_LOADER.plugins_path, } return list_detail.object_detail( request, Slice.objects.all(), object_id=slice_id, template_name=TEMPLATE_PATH + "/detail.html", template_object_name="slice", extra_context=dict(extra_context.items() + plugin_context.items()))
def delete(request, user_id): user = get_object_or_404(auth.models.User, pk=user_id) must_have_permission(request.user, user, "can_edit_user") return create_update.delete_object( request, auth.models.User, reverse("users_home"), user_id, template_name="expedient/clearinghouse/users/confirm_delete.html", )
def delete(request, user_id): user = get_object_or_404(auth.models.User, pk=user_id) must_have_permission(request.user, user, "can_edit_user") return create_update.delete_object( request, auth.models.User, reverse("users_home"), user_id, template_name="expedient/clearinghouse/users/confirm_delete.html", )
def delete(request, slice_id): '''Delete the slice''' slice = get_object_or_404(Slice, id=slice_id) project = slice.project #Slice can edited and used by anyone in the project, but only the owner of the slice #or the project's owner can delete it try: must_have_permission(request.user, slice, "can_delete_slices") except Exception,e: must_have_permission(request.user, project, "can_delete_slices")
def delete(request, slice_id): '''Delete the slice''' slice = get_object_or_404(Slice, id=slice_id) project = slice.project #Slice can edited and used by anyone in the project, but only the owner of the slice #or the project's owner can delete it try: must_have_permission(request.user, slice, "can_delete_slices") except Exception, e: must_have_permission(request.user, project, "can_delete_slices")
def home(request): '''show list of users and form for adding users''' must_have_permission(request.user, User, "can_manage_users") user_list = auth.models.User.objects.all().order_by('username') if request.method == "GET": pwd_form = auth.forms.UserCreationForm() user_form = users.forms.UserForm() userprofile_form = users.forms.UserProfileForm() elif request.method == "POST": pwd_form = auth.forms.UserCreationForm(request.POST) user_form = users.forms.UserForm(request.POST) userprofile_form = users.forms.UserProfileForm(request.POST) # check that all data is valid if pwd_form.is_valid() and user_form.is_valid( ) and userprofile_form.is_valid(): # create the user first user = pwd_form.save() # use the user to save the user info user_form = users.forms.UserForm(request.POST, instance=user) user = user_form.save() # now store the user profile up = users.models.UserProfile(user=user) userprofile_form = users.forms.UserProfileForm(request.POST, instance=up) userprofile_form.save() return HttpResponseRedirect( reverse("users_saved", args=(user.id, ))) else: return HttpResponseNotAllowed("GET", "POST") return simple.direct_to_template( request, template='expedient/clearinghouse/users/home.html', extra_context={ 'user_list': user_list, 'pwd_form': pwd_form, 'user_form': user_form, 'userprofile_form': userprofile_form, 'breadcrumbs': ( ("Home", reverse("home")), ("Manage users", request.path), ) }, )
def handle_add_to_slice(request, aggregate, slice): """Perform that actual add_to_slice request.""" must_have_permission(request.user, aggregate, "can_use_aggregate") must_have_permission(slice.project, aggregate, "can_use_aggregate") next = request.GET.get("next", None) give_permission_to("can_use_aggregate", aggregate, slice) #success_msg=lambda instance: "Successfully added OpenFlow aggregate %s to slice %s" % (aggregate.name, slice.name) return HttpResponseRedirect(next if next else reverse("slice_detail", args=[slice.id]))
def user_key_download(request, user_id): """Download a GCF key.""" user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_download_certs") key_fname = get_user_key_fname(user) response = HttpResponse(open(key_fname, 'r').read(), mimetype='application/force-download') response['Content-Disposition'] = 'attachment; filename=%s' % key_fname return response
def user_key_download(request, user_id): """Download a GCF key.""" user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_download_certs") key_fname = get_user_key_fname(user) response = HttpResponse(open(key_fname,'r').read(), mimetype='application/force-download') response['Content-Disposition'] = 'attachment; filename=%s' % key_fname return response
def handle_add_to_slice(request, aggregate, slice): """Perform that actual add_to_slice request.""" must_have_permission(request.user, aggregate, "can_use_aggregate") must_have_permission(slice.project, aggregate, "can_use_aggregate") next = request.GET.get("next", None) give_permission_to("can_use_aggregate", aggregate, slice) #success_msg=lambda instance: "Successfully added OpenFlow aggregate %s to slice %s" % (aggregate.name, slice.name) return HttpResponseRedirect( next if next else reverse("slice_detail", args=[slice.id]))
def user_cert_generate(request, user_id): """Create a new user certificate after confirmation. @param request: the request object @param user_id: the id of the user whose certificate we are generating. """ user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_change_user_cert") user_profile = UserProfile.get_or_create_profile(request.user) user_urn = user_profile.urn if request.method == "POST": #create_x509_cert(urn, cert_fname, key_fname) retValues = regenerate_member_creds(user_urn) if retValues: cert, cert_key, creds = retValues[0:] user_profile.certificate = cert user_profile.certificate_key = cert_key user_profile.credentials = creds user_profile.save() DatedMessage.objects.post_message_to_user( "Certificate for user %s successfully created." % user.username, user=request.user, msg_type=DatedMessage.TYPE_SUCCESS) return simple.direct_to_template( request, template=TEMPLATE_PATH + "/user_new_keys_download.html", extra_context={ "curr_user": user, }, ) else: DatedMessage.objects.post_message_to_user( "Certificate for user %s could not be created." % user.username, user=request.user, msg_type=DatedMessage.TYPE_ERROR) return HttpResponseRedirect( reverse(user_cert_manage, args=[user.id])) return simple.direct_to_template( request, template=TEMPLATE_PATH + "/user_cert_generate.html", extra_context={ "curr_user": user, }, )
def add_controller_to_slice(self, slice, next): """ Works exactly the same as L{add_to_project} but for a slice. """ must_have_permission("user", self.as_leaf_class(), "can_use_aggregate") must_have_permission("project", self.as_leaf_class(), "can_use_aggregate") prefix = self.__class__.get_url_name_prefix() try: return reverse("%s_aggregate_slice_controller_add" % prefix, kwargs={'agg_id': self.id, 'slice_id': slice.id})+"?next=%s" % next except NoReverseMatch: give_permission_to("can_use_aggregate", self.as_leaf_class(), slice) return next
def create(request, proj_id): '''Create a slice''' project = get_object_or_404(Project, id=proj_id) must_have_permission(request.user, project, "can_create_slices") #<UT> user_profile = UserProfile.get_or_create_profile(request.user) user_urn = user_profile.urn user_cert = user_profile.certificate def pre_save(instance, created): instance.project = project instance.owner = request.user #Generate UUID: fixes caching problem on model default value instance.uuid = uuid.uuid4() #<UT> instance.urn = 'n/a' #import pdb; pdb.set_trace() if settings.ENABLE_CBAS: slice_urn = create_slice(owner_urn=user_urn, owner_certificate=user_cert, slice_name=instance.name, slice_desc=instance.description, slice_project_urn=str(project.urn)) if slice_urn: instance.urn = slice_urn instance.save() instance.reserved = False #use to give the can_delete_slices over the slice to the creator and the owners of the project def post_save(instance, created): give_permission_to("can_delete_slices", instance, instance.owner, giver=None, can_delegate=False) # for projectOwner in instance.project._get_owners(): # give_permission_to("can_delete_slices", instance, projectOwner, giver=None, can_delegate=False) return generic_crud( request, None, Slice, TEMPLATE_PATH+"/create_update.html", redirect=lambda instance:reverse("slice_detail", args=[instance.id]), form_class=SliceCrudForm, extra_context={ "project": project, "title": "Create slice", "cancel_url": reverse("project_detail", args=[proj_id]), }, pre_save=pre_save, post_save=post_save, success_msg = lambda instance: "Successfully created slice %s." % instance.name, )
def create(request, proj_id): '''Create a slice''' project = get_object_or_404(Project, id=proj_id) must_have_permission(request.user, project, "can_create_slices") #<UT> from expedient.clearinghouse.users.models import UserProfile user_credentials = UserProfile.get_or_create_profile(request.user).credentials def pre_save(instance, created): instance.project = project instance.owner = request.user #Generate UUID: fixes caching problem on model default value instance.uuid = uuid.uuid4() #<UT> instance.credentials = 'n/a' if ENABLE_CBAS: code, values, output = create_slice(slice_name=instance.name, slice_desc=instance.description, user_credentials=[{'SFA': user_credentials}]) if code == 0 and 'SLICE_CREDENTIAL' in values: instance.credentials = values.SLICE_CREDENTIAL #import pdb; pdb.set_trace() instance.save() instance.reserved = False #use to give the can_delete_slices over the slice to the creator and the owners of the project def post_save(instance, created): give_permission_to("can_delete_slices", instance, instance.owner, giver=None, can_delegate=False) # for projectOwner in instance.project._get_owners(): # give_permission_to("can_delete_slices", instance, projectOwner, giver=None, can_delegate=False) return generic_crud( request, None, Slice, TEMPLATE_PATH+"/create_update.html", redirect=lambda instance:reverse("slice_detail", args=[instance.id]), form_class=SliceCrudForm, extra_context={ "project": project, "title": "Create slice", "cancel_url": reverse("project_detail", args=[proj_id]), }, pre_save=pre_save, post_save=post_save, success_msg = lambda instance: "Successfully created slice %s." % instance.name, )
def home(request): '''show list of users and form for adding users''' must_have_permission(request.user, User, "can_manage_users") user_list = auth.models.User.objects.all().order_by('username') if request.method == "GET": pwd_form = auth.forms.UserCreationForm() user_form = users.forms.UserForm() userprofile_form = users.forms.UserProfileForm() elif request.method == "POST": pwd_form = auth.forms.UserCreationForm(request.POST) user_form = users.forms.UserForm(request.POST) userprofile_form = users.forms.UserProfileForm(request.POST) # check that all data is valid if pwd_form.is_valid() and user_form.is_valid() and userprofile_form.is_valid(): # create the user first user = pwd_form.save() # use the user to save the user info user_form = users.forms.UserForm(request.POST, instance=user) user = user_form.save() # now store the user profile up = users.models.UserProfile(user=user) userprofile_form = users.forms.UserProfileForm(request.POST, instance=up) userprofile_form.save() return HttpResponseRedirect(reverse("users_saved", args=(user.id,))) else: return HttpResponseNotAllowed("GET", "POST") return simple.direct_to_template( request, template='expedient/clearinghouse/users/home.html', extra_context={ 'user_list': user_list, 'pwd_form': pwd_form, 'user_form': user_form, 'userprofile_form': userprofile_form, 'breadcrumbs': ( ("Home", reverse("home")), ("Manage users", request.path), ) }, )
def create(request, proj_id): '''Create a slice''' project = get_object_or_404(Project, id=proj_id) must_have_permission(request.user, project, "can_create_slices") #<UT> from expedient.clearinghouse.users.models import UserProfile user_credentials = UserProfile.get_or_create_profile(request.user).credentials def pre_save(instance, created): instance.project = project instance.owner = request.user #Generate UUID: fixes caching problem on model default value instance.uuid = uuid.uuid4() #<UT> #print "--------------------" code, values, output = create_slice(slice_name=instance.name, slice_desc=instance.description, user_credentials=user_credentials) if code == 0 and 'SLICE_CREDENTIAL' in values: instance.credentials = values.SLICE_CREDENTIAL import pdb; pdb.set_trace() instance.save() instance.reserved = False #use to give the can_delete_slices over the slice to the creator and the owners of the project def post_save(instance, created): give_permission_to("can_delete_slices", instance, instance.owner, giver=None, can_delegate=False) # for projectOwner in instance.project._get_owners(): # give_permission_to("can_delete_slices", instance, projectOwner, giver=None, can_delegate=False) return generic_crud( request, None, Slice, TEMPLATE_PATH+"/create_update.html", redirect=lambda instance:reverse("slice_detail", args=[instance.id]), form_class=SliceCrudForm, extra_context={ "project": project, "title": "Create slice", "cancel_url": reverse("project_detail", args=[proj_id]), }, pre_save=pre_save, post_save=post_save, success_msg = lambda instance: "Successfully created slice %s." % instance.name, )
def update(request, slice_id): '''Update a slice's information''' project = get_object_or_404(Project, slice__pk=slice_id) must_have_permission(request.user, project, "can_edit_slices") return generic_crud( request, slice_id, Slice, TEMPLATE_PATH+"/create_update.html", redirect=lambda instance:reverse("slice_detail", args=[instance.id]), extra_context={ "title": "Create slice", "cancel_url": reverse("slice_detail", args=[slice_id]), }, form_class=SliceCrudForm, success_msg = lambda instance: "Successfully updated slice %s." % instance.name, )
def remove_aggregate(request, slice_id, agg_id): slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_edit_slices") aggregate = get_object_or_404(Aggregate, id=agg_id, id__in=slice.aggregates.values_list( "id", flat=True)).as_leaf_class() if request.method == "POST": return HttpResponseRedirect( aggregate.remove_from_slice( slice, reverse("slice_detail", args=[slice_id]))) else: return HttpResponseNotAllowed(["POST"])
def user_cert_generate(request, user_id): """Create a new user certificate after confirmation. @param request: the request object @param user_id: the id of the user whose certificate we are generating. """ user = get_object_or_404(User, pk=user_id) must_have_permission(request.user, user, "can_change_user_cert") user_profile = UserProfile.get_or_create_profile(request.user) user_urn = user_profile.urn if request.method == "POST": #create_x509_cert(urn, cert_fname, key_fname) retValues = regenerate_member_creds(user_urn) if retValues: cert, cert_key, creds = retValues[0:] user_profile.certificate = cert user_profile.certificate_key = cert_key user_profile.credentials = creds user_profile.save() DatedMessage.objects.post_message_to_user( "Certificate for user %s successfully created." % user.username, user=request.user, msg_type=DatedMessage.TYPE_SUCCESS) return simple.direct_to_template( request, template= TEMPLATE_PATH + "/user_new_keys_download.html", extra_context={ "curr_user": user, }, ) else: DatedMessage.objects.post_message_to_user( "Certificate for user %s could not be created." % user.username, user=request.user, msg_type=DatedMessage.TYPE_ERROR) return HttpResponseRedirect(reverse(user_cert_manage, args=[user.id])) return simple.direct_to_template( request, template= TEMPLATE_PATH + "/user_cert_generate.html", extra_context={ "curr_user": user, }, )
def update_aggregate(request, slice_id, agg_id): '''Update any info stored at the aggregate''' slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_edit_slices") aggregate = get_object_or_404( Aggregate, id=agg_id, id__in=slice.aggregates.values_list( "id", flat=True)).as_leaf_class() if request.method == "POST": #return HttpResponseRedirect(aggregate.add_to_slice( return HttpResponseRedirect(aggregate.add_controller_to_slice( slice, reverse("slice_detail", args=[slice_id]))) else: return HttpResponseNotAllowed(["POST"])
def create(request, proj_id): '''Create a slice''' project = get_object_or_404(Project, id=proj_id) must_have_permission(request.user, project, "can_create_slices") def pre_save(instance, created): instance.project = project instance.owner = request.user #Generate UUID: fixes caching problem on model default value instance.uuid = uuid.uuid4() instance.save() instance.reserved = False #use to give the can_delete_slices over the slice to the creator and the owners of the project def post_save(instance, created): give_permission_to("can_delete_slices", instance, instance.owner, giver=None, can_delegate=False) # for projectOwner in instance.project._get_owners(): # give_permission_to("can_delete_slices", instance, projectOwner, giver=None, can_delegate=False) return generic_crud( request, None, Slice, TEMPLATE_PATH + "/create_update.html", redirect=lambda instance: reverse("slice_detail", args=[instance.id]), form_class=SliceCrudForm, extra_context={ "project": project, "title": "Create slice", "cancel_url": reverse("project_detail", args=[proj_id]), }, pre_save=pre_save, post_save=post_save, success_msg=lambda instance: "Successfully created slice %s." % instance.name, )
def add_aggregate(request, slice_id): '''Add aggregate to slice''' slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_edit_slices") aggregate_list = slice.project.aggregates.exclude( id__in=slice.aggregates.values_list("id", flat=True)) if request.method == "GET": return simple.direct_to_template( request, template=TEMPLATE_PATH + "/add_aggregates.html", extra_context={ "aggregate_list": aggregate_list, "slice": slice, "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % slice.project.name, reverse("project_detail", args=[slice.project.id])), ("Slice %s" % slice.name, reverse("slice_detail", args=[slice_id])), ("Add Slice Aggregates", request.path), ), }) elif request.method == "POST": # check which submit button was pressed try: agg_id = int(request.POST.get("id", 0)) except ValueError: raise Http404 if agg_id not in aggregate_list.values_list("id", flat=True): raise Http404 aggregate = get_object_or_404(Aggregate, id=agg_id).as_leaf_class() return HttpResponseRedirect( aggregate.add_to_slice(slice, reverse("slice_add_agg", args=[slice_id]))) else: return HttpResponseNotAllowed("GET", "POST")
def start(request, slice_id): '''Start the slice on POST''' slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_start_slices") if request.method == "POST": if False in slice._get_aggregates().values_list("available", flat=True): DatedMessage.objects.post_message_to_user( "Slice %s can not be started because some of its AMs is not available" % slice.name, request.user, msg_type=DatedMessage.TYPE_ERROR) return HttpResponseRedirect( reverse("slice_detail", args=[slice_id])) try: excs = slice.start(request.user) except Exception as e: import traceback traceback.print_exc() print e DatedMessage.objects.post_message_to_user( "Error starting slice %s: %s" % (slice.name, parseFVexception(e)), user=request.user, msg_type=DatedMessage.TYPE_ERROR) else: if not excs: DatedMessage.objects.post_message_to_user( "Successfully started slice %s" % slice.name, request.user, msg_type=DatedMessage.TYPE_SUCCESS) else: DatedMessage.objects.post_message_to_user( "Slice %s was started, but some AMs could not be started. Double check your VMs status" % slice.name, request.user, msg_type=DatedMessage.TYPE_SUCCESS) return HttpResponseRedirect(reverse("slice_detail", args=[slice_id])) else: return HttpResponseNotAllowed(["POST"])
def save(self, *args, **kwargs): """ Override the default save method to enforce permissions. """ pk = getattr(self, "pk", None) if not pk: # it's a new instance being created must_have_permission(permittee_kw, model_func(), create_perm) else: must_have_permission(permittee_kw, self, edit_perm) super(model_func(), self).save(*args, **kwargs) if not pk: # it was just created so give creator edit permissions d = threadlocals.get_thread_locals() give_permission_to( edit_perm, self, d[permittee_kw], can_delegate=True) give_permission_to( delete_perm, self, d[permittee_kw], can_delegate=True)
def remove_from_slice(self, slice, next): """ Works exactly the same as L{remove_from_project} but for a slice. It stops the slice if not overridden. Subclasses should stop the slice before removing the permission. """ must_have_permission("user", self.as_leaf_class(), "can_use_aggregate") must_have_permission("project", self.as_leaf_class(), "can_use_aggregate") prefix = self.__class__.get_url_name_prefix() try: return reverse("%s_aggregate_slice_remove" % prefix, kwargs={'agg_id': self.id, 'slice_id': slice.id})+"?next=%s" % next except NoReverseMatch: try: self.as_leaf_class().stop_slice(slice) except: pass delete_permission("can_use_aggregate", self.as_leaf_class(), slice) return next
def add_to_project(self, project, next): """ Gives the aggregate a chance to request additional information for a project. This method should return a URL to redirect to where the user can create or update the additional information the aggregate needs. When done, the view at that URL should use the C{give_permission} function to give the project the "can_use_aggregate" permission:: from expedient.common.permissions.shortcuts import \ give_permission_to give_permission_to("can_use_aggregate", self.as_leaf_class(), project) and then it should redirect to C{next}. If no extra information is needed, this function can return C{next}, instead of a custom URL, but it still needs to give the project the "can_use_aggregate" permission. Unless overridden in a subclass, this function will look for a url with name <app_name>_aggregate_project_add by reversing the name with it parameters 'agg_id' and 'proj_id'. It will append '?next=<next>' to the URL if found. Otherwise, it simply gives the permission to the project and returns C{next}. """ logger.debug("adding aggregate to project") must_have_permission("user", self.as_leaf_class(), "can_use_aggregate") prefix = self.__class__.get_url_name_prefix() try: return reverse("%s_aggregate_project_add" % prefix, kwargs={'agg_id': self.id, 'proj_id': project.id})+"?next=%s" % next except NoReverseMatch: logger.debug("Giving permission to use aggregate to %s" % project) give_permission_to("can_use_aggregate", self.as_leaf_class(), project) return next
def add_aggregate(request, slice_id): '''Add aggregate to slice''' slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_edit_slices") aggregate_list = slice.project.aggregates.exclude( id__in=slice.aggregates.values_list("id", flat=True)) if request.method == "GET": return simple.direct_to_template( request, template=TEMPLATE_PATH+"/add_aggregates.html", extra_context={ "aggregate_list": aggregate_list, "slice": slice, "breadcrumbs": ( ("Home", reverse("home")), ("Project %s" % slice.project.name, reverse("project_detail", args=[slice.project.id])), ("Slice %s" % slice.name, reverse("slice_detail", args=[slice_id])), ("Add Slice Aggregates", request.path), ), } ) elif request.method == "POST": # check which submit button was pressed try: agg_id = int(request.POST.get("id", 0)) except ValueError: raise Http404 if agg_id not in aggregate_list.values_list("id", flat=True): raise Http404 aggregate = get_object_or_404(Aggregate, id=agg_id).as_leaf_class() return HttpResponseRedirect(aggregate.add_to_slice( slice, reverse("slice_add_agg", args=[slice_id]))) else: return HttpResponseNotAllowed("GET", "POST")
def start(request, slice_id): '''Start the slice on POST''' slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_start_slices") if request.method == "POST": if False in slice._get_aggregates().values_list("available",flat=True): DatedMessage.objects.post_message_to_user( "Slice %s can not be started because some of its AMs is not available" % slice.name, request.user, msg_type=DatedMessage.TYPE_ERROR) return HttpResponseRedirect(reverse("slice_detail", args=[slice_id])) try: excs = slice.start(request.user) except Exception as e: import traceback traceback.print_exc() print e DatedMessage.objects.post_message_to_user( "Error starting slice %s: %s" % ( slice.name, parseFVexception(e)), user=request.user, msg_type=DatedMessage.TYPE_ERROR) else: if not excs: DatedMessage.objects.post_message_to_user( "Successfully started slice %s" % slice.name, request.user, msg_type=DatedMessage.TYPE_SUCCESS) else: DatedMessage.objects.post_message_to_user( "Slice %s was started, but some AMs could not be started. Double check your VMs status" % slice.name, request.user, msg_type=DatedMessage.TYPE_SUCCESS) return HttpResponseRedirect(reverse("slice_detail", args=[slice_id])) else: return HttpResponseNotAllowed(["POST"])
def remove_aggregate(request, slice_id, agg_id): slice = get_object_or_404(Slice, id=slice_id) must_have_permission(request.user, slice.project, "can_edit_slices") aggregate = get_object_or_404( Aggregate, id=agg_id, id__in=slice.aggregates.values_list( "id", flat=True)).as_leaf_class() if request.method == "POST": try: return HttpResponseRedirect(aggregate.remove_from_slice( slice, reverse("slice_detail", args=[slice_id]))) except MultipleObjectsReturned as e: DatedMessage.objects.post_message_to_user( str(e), request.user, msg_type=DatedMessage.TYPE_ERROR) except: pass # If any error occurs, redirect to slice detail page return HttpResponseRedirect( reverse('slice_detail', args=[slice_id])) else: return HttpResponseNotAllowed(["POST"])