Example #1
0
def topology_access_check(request, callee, action, **kwargs):
    """Checks that the user can access the functions they're trying to, and
    if they can calls callee.  There are two valid authentication methods - 
    django logihn, as normally used for the website, and a cryptographic token
    supplied in the HTTP GET, as used for clack.
    @param request  An HTTP request
    @param callee  Gives the Callable to call
    @param action  One of "add", "change", "use", "delete", describing the
    permissions needed
    @param tid  The ID of the topology in question; not used for
    action = "add"
    @exception ValueError  If an action is unrecognised
    @exception KeyError  If an option is missing
    @return HttpResponse"""

    def denied():
        """Generate an error message and redirect if we try do something to a
        topology we're not allowed to"""
        messages.error(request, "Either this topology doesn't exist or you don't "
                                "have permission to %s it." % action)
        return HttpResponseRedirect('/login/')

    def denied_add():
        """Generate an error message and redirect if we try to create a topology
        and are not allowed to"""
        messages.error(request, "You don't have permission to create topologies.")
        return HttpResponseRedirect('/login/')

    
    # If we're trying to add a template, don't need to get the template itself
    if action == "add":
        if permissions.allowed_topology_access_create(request.user):
            return callee(request)
        else:
            return denied_add()

    else:

        # Try getting the template - if it doesn't exist, show the same message
        # as for permission denied.  If we don't have a "tid" argument, django
        # will show an internal error, which is what we want.
        tid = int(kwargs["tid"])
        kwargs["tid"] = tid
        try :
            topo = db.Topology.objects.get(pk=tid)
        except db.Topology.DoesNotExist:
            return denied()

        if action == "use":
            # See if there is an HTTP GET token - if there is, try to use the token
            # method for authentication
            try:
                token = request.GET["token"]
            except KeyError:
                pass
            else:
                # See if the token is valid
                user = crypto.validate_token(token)
                if user != None and permissions.allowed_topology_access_use(user, topo):
                    request.user = user
                    return callee(request, topo=topo, **kwargs)
            if permissions.allowed_topology_access_use(request.user, topo):
                 return callee(request, topo=topo, **kwargs)
            else:
                return denied()

        elif action == "change":
            if permissions.allowed_topology_access_change(request.user, topo):
                return callee(request, topo=topo, **kwargs)
            else:
                return denied()
        elif action == "delete":
            if permissions.allowed_topology_access_delete(request.user, topo):
                return callee(request, topo=topo, **kwargs)
            else:
                return denied()
        else:
            raise ValueError("Unknown action: %s" % options["action"])
Example #2
0
def group_topology_create(request, group, **kwargs):
    """Create topologies for a group, with each user in the group becoming the
    owner of one topology.
    @param request  An HttpRequest
    @param group  The group to add the topologies for"""

    tn = "vns/group_topology_create.html"

    # Check we're allowed to create topologies
    if not permissions.allowed_topology_access_create(request.user):
        messages.info("Please login as a user who is permitted to create topologies.")
        return HttpResponseRedirect('/login/?next=/topology/create/')

    # Import a function to create the form
    CreateTopologyForm = make_ctform(request.user)
    
    if request.method == "POST":
        form = CreateTopologyForm(request.POST)
        if form.is_valid():
            template_id = form.cleaned_data['template']
            ipblock_id = form.cleaned_data['ipblock']
            num_to_create = form.cleaned_data['num_to_create']
            ip = form.cleaned_data['ip_subnet']
            mask = form.cleaned_data['ip_subnet_mask']

            # Do lots of permissions and existence checks - need a topology
            # template and IP block
            try:
                template = db.TopologyTemplate.objects.get(pk=template_id)
            except db.TopologyTemplate.DoesNotExist:
                messages.error(request, "No such template")
                return direct_to_template(request, tn, { 'form': form,
                                                         'group': group})

            try:
                ipblock = db.IPBlock.objects.get(pk=ipblock_id)
            except db.IPBlock.DoesNotExist:
                messages.error(request, "No such IP block")
                return direct_to_template(request, tn, { 'form': form,
                                                         'group': group})

            if not permissions.allowed_topologytemplate_access_use(request.user, template):
                messages.error(request, "You cannot create topologies from this template")
                return direct_to_template(request, tn, { 'form': form,
                                                         'group': group})
            
            if not permissions.allowed_ipblock_access_use(request.user, ipblock):
                messages.error(request, "You cannot create topologies in this IP block")
                return direct_to_template(request, tn, { 'form': form,
                                                         'group': group})

            if num_to_create > 5:
                messages.error(request, "You cannot create >5 topologies / user at once")
                return direct_to_template(request, tn, { 'form': form,
                                                         'group': group})
            # Get a list of users
            try:
                users = User.objects.filter(vns_groups=group)
            except User.DoesNotExist:
                messages.error("No users in this group to create topologies for")
                return HttpResponseRedirect("/")

            # Tell the DBService module to use this thread for accessing the DB
            DBService.thread = threading.current_thread()

            # Otherwise, we're good to actually create the topologies, subject
            # to permissions checks on each user.
            # These variables track the number with permissions errors, the
            # number successfully created and the number rwith other errors
            # to report to the user.
            num_perms = 0
            num_created = 0
            num_errs = 0
            for u in users:
                
                # Check we have permission to change this user
                if not permissions.allowed_user_access_change(request.user, u):
                    num_perms += 1
                    continue

                # Make a list of source IP filters
                if ip != None and mask != None:
                    src_filters = [(ip, mask)]
                else:
                    src_filters = []

                # Create the topology
                for _ in xrange(0,num_to_create):

                    err,_,_,_ = instantiate_template(org=u.get_profile().org,
                                                     owner=u,
                                                     template=template,
                                                     ip_block_from=ipblock,
                                                     src_filters=src_filters,
                                                     temporary=False,
                                                     use_recent_alloc_logic=False,
                                                     public=False,
                                                     use_first_available=True)
                
                    # Update the numbers with/without errors
                    if err is not None:
                        num_errs += 1
                    else:
                        num_created += 1

            # Report to the user
            topology_create_message(request, num_errs, num_perms, num_created)
            return HttpResponseRedirect('/org/%s/%s/' % (group.org.name, group.name))

        else:
            # The form is not valid
            messages.error(request, "Invalid form")
            return direct_to_template(request, tn, {'form':form,
                                                    'group':group})

    else:
        # request.method != 'POST'
        # Need to give them a form but do nothing else
        return direct_to_template(request, tn, {'form':CreateTopologyForm(),
                                                'group':group})
Example #3
0
def topology_create(request):
    # make sure the user is logged in
    if not permissions.allowed_topology_access_create(request.user):
        messages.info("Please login as a user who is permitted to create topologies.")
        return HttpResponseRedirect('/login/?next=/topology/create/')

    tn = 'vns/topology_create.html'
    CTForm = make_ctform(request.user)
    if request.method == 'POST':
        form = CTForm(request.POST)
        if form.is_valid():
            template_id = form.cleaned_data['template']
            ipblock_id = form.cleaned_data['ipblock']
            num_to_create = form.cleaned_data['num_to_create']

            try:
                template = db.TopologyTemplate.objects.get(pk=template_id)
            except db.TopologyTemplate.DoesNotExist:
                messages.error(request, "No such template")
                return direct_to_template(request, tn, { 'form': form })

            try:
                ipblock = db.IPBlock.objects.get(pk=ipblock_id)
            except db.IPBlock.DoesNotExist:
                messages.error(request, "No such IP block")
                return direct_to_template(request, tn, { 'form': form })

            if not permissions.allowed_topologytemplate_access_use(request.user, template):
                messages.error(request, "You cannot create topologies from this template")
                return direct_to_template(request, tn, { 'form': form })
            
            if not permissions.allowed_ipblock_access_use(request.user, ipblock):
                messages.error(request, "You cannot create topologies in this IP block")
                return direct_to_template(request, tn, { 'form': form })

            if num_to_create > 30:
                messages.error(request, "You cannot create >30 topologies at once")
                return direct_to_template(request, tn, { 'form': form })

            # TODO: should validate that request.user can use the requested
            #       template and IP block

            # Tell the DBService that we want to make the database calls from this thread
            DBService.thread = threading.current_thread()

            # try to create the topologies
            src_filters = []
            for i in range(num_to_create):
                err, _, _, _ = instantiate_template(request.user.get_profile().org,
                                                    request.user,
                                                    template,
                                                    ipblock,
                                                    src_filters,
                                                    temporary=False,
                                                    use_recent_alloc_logic=False,
                                                    public=False,
                                                    use_first_available=True)
                if err is not None:
                    messages.error(request, "Successfully allocated %d '%s' topologies from %s.  Failed to make the other request topologies: %s." % (i, template.name, ipblock, err))
                    return direct_to_template(request, tn)
            messages.success(request, "Successfully allocated %d '%s' topologies from %s." % (num_to_create, template.name, ipblock))
            return direct_to_template(request, tn)
    else:
        form = CTForm()

    return direct_to_template(request, tn, { 'form': form })
Example #4
0
File: models.py Project: smbz/vns
 def can_create_topology(self):
     return permissions.allowed_topology_access_create(self.user)