Example #1
0
def start_export_run_view(request, project_slug, export_run_id):
    if request.method != "POST":
        logger.debug("method is not POST, but {0}".format(request.method))
        return HttpResponseForbidden()

    try:
        export_run = models.ExportRun.objects.get(pk=export_run_id)
    except models.ExportRun.DoesNotExist:
        logger.debug("No such export run")
        return HttpResponseForbidden()

    if export_run.project.slug != project_slug:
        logger.debug("Wrong project slug")
        return HttpResponseForbidden()

    if not models.has_access(
        request.user, export_run.project, export_run.contractor):
        logger.debug("No access")
        return HttpResponseForbidden()

    # Clear existing export
    export_run.clear()
    export_run.export_running = True
    export_run.save()

    # Start the Celery task
    tasks.start_export_run.delay(export_run.id, request.user)

    return HttpResponse()
Example #2
0
    def get(self, request, *args, **kwargs):
        self.project_slug = kwargs.get('project_slug', None)
        self.project = get_object_or_404(
            models.Project, slug=self.project_slug)

        if not self.project.can_upload(request.user):
            return HttpResponseForbidden()

        try:
            self.contractor = models.Contractor.objects.get(
                project=self.project,
                organization__userprofile__user=request.user)
        except models.Contractor.DoesNotExist:
            self.contractor = None

        if not models.has_access(request.user, self.project):
            return HttpResponseForbidden()

        if not self.contractor:
            return []

        return HttpResponse(
            json.dumps([
                    uploaded_file.as_dict()
                    for uploaded_file in
                    models.UploadedFile.objects.filter(
                        project=self.project,
                        contractor=self.contractor)]),
            content_type="application/json")
Example #3
0
    def projects(self):
        """Returns a list of projects the current user has access to."""

        projects = []
        for project in Project.objects.all():
            if has_access(self.request.user, project):
                projects.append(project)
        return projects
Example #4
0
def protected_file_download(request, project_slug, contractor_slug,
                                   measurement_type_slug, filename):
    """
    We need our own file_download view because contractors can only see their
    own files, and the URLs of other contractor's files are easy to guess.

    Copied and adapted from deltaportaal, which has a more generic
    example, in case you're looking for one. It is for Apache.

    The one below works for both Apache (untested) and Nginx.  I used
    the docs at http://wiki.nginx.org/XSendfile for the Nginx
    configuration.  Basically, Nginx serves /protected/ from the
    document root at BUILDOUT_DIR+'var', and we x-accel-redirect
    there. Also see the bit of nginx conf in hdsr's etc/nginx.conf.in.
    """

    project = get_object_or_404(Project, slug=project_slug)
    contractor = get_object_or_404(Contractor, slug=contractor_slug,
                                   project=project)
    mtype = get_object_or_404(
        MeasurementType, mtype__slug=measurement_type_slug,
        project=project)

    logger.debug("Incoming programfile request for %s", filename)

    if '/' in filename or '\\' in filename:
        # Trickery?
        logger.warn("Returned Forbidden on suspect path %s" % (filename,))
        return http.HttpResponseForbidden()

    if not has_access(request.user, project, contractor):
        logger.warn("Not allowed to access %s", filename)
        return http.HttpResponseForbidden()

    file_path = directories.make_uploaded_file_path(
        directories.BASE_DIR, project, contractor,
        mtype, filename)
    nginx_path = directories.make_uploaded_file_path(
        '/protected', project, contractor,
        mtype, filename)

    # This is where the magic takes place.
    response = http.HttpResponse()
    response['X-Sendfile'] = file_path  # Apache
    response['X-Accel-Redirect'] = nginx_path  # Nginx

    # Unset the Content-Type as to allow for the webserver
    # to determine it.
    response['Content-Type'] = ''

    # Only works for Apache and Nginx, under Linux right now
    if settings.DEBUG or not platform.system() == 'Linux':
        logger.debug(
            "With DEBUG off, we'd serve the programfile via webserver: \n%s",
            response)
        return serve(request, file_path, '/')
    return response
Example #5
0
    def dispatch(self, request, *args, **kwargs):
        self.request = request
        self.user = request.user
        self.profile = models.UserProfile.get_by_user(self.user)

        self.project_slug = kwargs.get('project_slug')
        if self.project_slug:
            self.project = get_object_or_404(Project, slug=self.project_slug)
            if has_access(request.user, self.project):
                self.has_full_access = all(
                    has_access(request.user, self.project, contractor)
                    for contractor in self.project.contractor_set.all())
            else:
                raise PermissionDenied()
        else:
            self.project = None

        return super(
            ProjectsMixin, self).dispatch(request, *args, **kwargs)
Example #6
0
    def get(self, request, filetype, project_slug,
            contractor_slug, filename):
        project = get_object_or_404(Project, slug=project_slug)
        if contractor_slug == 'x':
            contractor = None
        else:
            contractor = get_object_or_404(Contractor, slug=contractor_slug)

        if not has_access(request.user, project, contractor):
            return HttpResponseForbidden()

        if filetype == 'reports':
            directory = directories.reports_dir(project, contractor)
        elif filetype == 'results':
            directory = directories.reports_dir(project, contractor)
        elif filetype == 'locations':
            logger.debug("Looking for {0}".format(filename))
            directory = directories.location_shapefile_dir(project, contractor)
            logger.debug("Trying in {0}".format(directory))
            for path in directories.all_files_in(directory):
                logger.debug("... {0}".format(path))
                if os.path.basename(path) == filename:
                    directory = os.path.dirname(path)
                    break
            else:
                raise http.Http404()
        elif filetype == 'organization':
            directory = directories.organization_files_dir(
                project.organization)
        elif filetype == 'hydrovakken':
            directory = directories.hydrovakken_dir(project)
            for path in directories.all_files_in(directory):
                if os.path.basename(path) == filename:
                    directory = os.path.dirname(path)
                    break
            else:
                raise http.Http404()
        elif filetype == 'contractor_hydrovakken':
            directory = directories.shapefile_dir(project, contractor)
            for path in directories.all_files_in(directory):
                if os.path.basename(path) == filename:
                    directory = os.path.dirname(path)
                    break
            else:
                raise http.Http404()
        else:
            return HttpResponseForbidden()

        path = os.path.join(directory, filename)

        if not os.path.exists(path):
            raise http.Http404()

        return serve(request, path, '/')
Example #7
0
    def available_layers(self):
        """List of layers available to draw. Per contractor per area,
        there is one layer for each measurement type and one layer
        that shows all measurement types simultaneously. If the user
        has access to that contractor's data."""

        logger.debug("Available layers:")
        layers = []
        for contractor in self.project.contractor_set.all():
            if has_access(self.request.user, self.project, contractor):
                mtype_layers = []
                for measurement_type in self.project.measurementtype_set.all():
                    if (measurement_type.mtype.can_be_displayed
                        and contractor.show_measurement_type(
                            measurement_type)):
                        mtype_layers.append({
                                'name': '%s %s %s' %
                                (self.project.name,
                                 contractor.name,
                                 measurement_type.name),
                                'adapter': 'adapter_progress',
                                'json': json.dumps({
                                        "contractor_slug":
                                            contractor.slug,
                                        "measurement_type_slug":
                                            measurement_type.slug,
                                        "project_slug":
                                            self.project.slug}),
                                })

                if len(mtype_layers) > 1:
                    layers.append({
                            'name': '%s %s Alle metingen'
                            % (self.project.name, contractor.name),
                            'adapter': 'adapter_progress',
                            'json': json.dumps({
                                    "contractor_slug":
                                        contractor.slug,
                                    "project_slug":
                                        self.project.slug})
                            })
                layers += mtype_layers

        if Hydrovak.objects.filter(project=self.project).exists():
            layers.append({
                'name': 'Hydrovakken {projectname}'
                .format(projectname=self.project.name),
                'adapter': 'adapter_hydrovak',
                'json': json.dumps({"project_slug": self.project_slug})
            })

        return layers
Example #8
0
    def __location_shapefiles(self):
        """For all the combinations of contractor and measurement type in this
        project, check if the shapefile exists, and if so return its path and
        the measurement type and contractor."""

        for mtype in models.MeasurementType.objects.filter(
            project=self.project):
            for contractor in Contractor.objects.filter(project=self.project):
                if has_access(self.user, self.project, contractor):
                    shapefile_path = directories.location_shapefile_path(
                        self.project, contractor, mtype.mtype)
                    if os.path.exists(shapefile_path + ".shp"):
                        yield shapefile_path, contractor, mtype
Example #9
0
    def dispatch(self, request, *args, **kwargs):
        """Check access (user needs to be able to read data of all
        contractors), and find the current measurement type, if any."""

        self.mtype_slug = kwargs.get('mtype_slug', None)

        result = super(ComparisonView, self).dispatch(request, *args, **kwargs)

        for contractor in self.project.contractor_set.all():
            if not has_access(request.user, self.project, contractor):
                raise PermissionDenied()

        return result
Example #10
0
 def _results_files(self):
     for contractor in self.project.contractor_set.all():
         if has_access(self.user, self.project, contractor):
             for path in directories.files_in(
                 directories.results_dir(self.project, contractor)):
                     yield {
                     'type': 'Resultaten {0}'.format(
                         contractor.organization.name),
                     'filename': os.path.basename(path),
                     'size': directories.human_size(path),
                     'url': self._make_url('results',
                                           self.project,
                                           contractor,
                                           path)
                     }
Example #11
0
 def _shapefile_files(self):
     for contractor in self.project.contractor_set.all():
         if has_access(self.user, self.project, contractor):
             for path in directories.all_files_in(
                 directories.shapefile_dir(
                     self.project, contractor)):
                     yield {
                         'type': 'Ingevulde hydrovakken shapefile '.format(
                             contractor.organization.name),
                         'filename': os.path.basename(path),
                         'size': directories.human_size(path),
                         'url': self._make_url(
                             'contractor_hydrovakken', self.project,
                             contractor, path)
                     }
 def test_has_access_contractor(self):
     """Test access for contractor to a project."""
     uploader = UserF.create(username="******", is_superuser=False)
     uploaderorganization = OrganizationF.create(name="Uploader organization")
     UserProfileF.create(
         user=uploader, organization=uploaderorganization)
     projectorganization = OrganizationF.create(name="organization")
     projectuser = UserF(is_superuser=True)
     project = ProjectF.create(superuser=projectuser)
     UserProfileF.create(
         user=projectuser, organization=projectorganization)
     contractor = ContractorF(
         project=project, organization=uploaderorganization)
     has_access = models.has_access(uploader, project, contractor)
     self.assertEquals(has_access, True)
Example #13
0
    def areas(self):
        """The areas for which to show popup links. Shows each area
        for each contractor the user has access to."""

        areas = []
        for contractor in Contractor.objects.filter(project=self.project):
            if has_access(self.request.user, self.project, contractor):
                for area in Area.objects.filter(project=self.project):
                    areas.append((contractor, area,
                                  reverse('lizard_progress_dashboardareaview',
                                          kwargs={
                                    'contractor_slug': contractor.slug,
                                    'project_slug': self.project.slug,
                                    'area_slug': area.slug})))

        return areas
Example #14
0
    def dispatch(self, request, *args, **kwargs):
        """Find project and contractor objects. A successful upload
        can only be performed by a contractor for some specific
        project.  Check if user has access to this project, and if he
        can upload files."""

        self.project_slug = kwargs.get('project_slug', None)
        self.project = get_object_or_404(
            models.Project, slug=self.project_slug)

        if not models.has_access(request.user, self.project):
            return HttpResponseForbidden()

        self.user = request.user

        return super(UploadView, self).dispatch(
            request, *args, **kwargs)
Example #15
0
 def _hydrovakken_files(self):
     if has_access(self.user, self.project):
         for path in directories.all_files_in(
             directories.hydrovakken_dir(self.project),
             extension=".shp"):
             yield {
             'description':
                 "Hydrovakken {project}".format(project=self.project),
             'urls': {
                 'shp': self._make_url(
                         'hydrovakken', self.project, None, path),
                 'dbf': self._make_url(
                         'hydrovakken', self.project, None,
                         path.replace('.shp', '.dbf')),
                 'shx': self._make_url(
                         'hydrovakken', self.project, None,
                         path.replace('.shp', '.shx'))
                 }}
Example #16
0
    def get(self, request, *args, **kwargs):
        self.project_slug = kwargs.get('project_slug', None)
        self.project = get_object_or_404(
            models.Project, slug=self.project_slug)

        if not self.project.can_upload(request.user):
            return HttpResponseForbidden()

        try:
            self.contractor = models.Contractor.objects.get(
                project=self.project,
                organization__userprofile__user=request.user)
        except models.Contractor.DoesNotExist:
            self.contractor = None

        if models.has_access(request.user, self.project):
            return super(UploadHomeView, self).get(request, *args, **kwargs)
        else:
            return HttpResponseForbidden()
Example #17
0
    def dispatch(self, request, *args, **kwargs):
        """Get objects project, area and contractor from the request,
        404 if they are not found. Check if the user has access."""

        self.project_slug = kwargs.get('project_slug', None)
        self.project = get_object_or_404(Project, slug=self.project_slug)
        self.area_slug = kwargs.get('area_slug', None)
        if self.area_slug:
            self.area = get_object_or_404(Area,
                                          project=self.project,
                                          slug=self.area_slug)
        self.contractor_slug = kwargs.get('contractor_slug', None)
        self.contractor = get_object_or_404(Contractor,
                                            project=self.project,
                                            slug=self.contractor_slug)

        if not has_access(request.user, self.project, self.contractor):
            raise PermissionDenied()

        return (super(DashboardAreaView, self).
                dispatch(request, *args, **kwargs))
Example #18
0
    def csv(self):
        """Links to CSV downloads. One per contractor."""

        if hasattr(self, '_csvs'):
            return self._csvs

        csvs = []

        for contractor in Contractor.objects.filter(project=self.project):
            if has_access(self.request.user, self.project, contractor):
                url = reverse(
                    'lizard_progress_dashboardcsvview',
                    kwargs={
                        'project_slug': self.project_slug,
                        'contractor_slug': contractor.slug,
                        })

                csvs.append((contractor, url))

        self._csvs = csvs
        return csvs
Example #19
0
    def dispatch(self, request, *args, **kwargs):
        """Check access (user needs to be able to read data of all
        contractors), find current measurement type and location."""

        self.mtype_slug = kwargs.get('mtype_slug', None)
        self.measurement_type = MeasurementType.objects.get(
            project=self.project,
            mtype__slug=self.mtype_slug)

        self.location_code = kwargs.get('location_code', None)
        self.location = Location.objects.get(
            project=self.project,
            location_code=self.location_code)

        result = super(ComparisonPopupView, self).dispatch(
            request, *args, **kwargs)

        for contractor in self.project.contractor_set.all():
            if not has_access(request.user, self.project, contractor):
                raise PermissionDenied()

        return result
Example #20
0
def protected_download_export_run(request, project_slug, export_run_id):
    """
    Copied from views.protected_file_download, see there.
    No Apache support, only Nginx.
    """

    try:
        export_run = models.ExportRun.objects.get(pk=export_run_id)
    except models.ExportRun.DoesNotExist:
        return HttpResponseForbidden()

    if export_run.project.slug != project_slug:
        return HttpResponseForbidden()

    if not has_access(request.user, export_run.project, export_run.contractor):
        return HttpResponseForbidden()

    file_path = export_run.file_path
    logger.debug("File path: " + file_path)

    nginx_path = '/'.join([
            '/protected', 'export',
            export_run.project.organization.name,
            os.path.basename(file_path)])

    # This is where the magic takes place.
    response = HttpResponse()
    response['X-Accel-Redirect'] = nginx_path  # Nginx

    # Unset the Content-Type as to allow for the webserver
    # to determine it.
    response['Content-Type'] = ''

    # Only works for Apache and Nginx, under Linux right now
    if settings.DEBUG or not platform.system() == 'Linux':
        return serve(request, file_path, '/')
    return response
Example #21
0
def dashboard_graph(request, project_slug, contractor_slug,
                    area_slug, *args, **kwargs):
    """Show the work in progress per area in pie charts.

    A single PNG image is returned as a response.
    """
    project = get_object_or_404(Project, slug=project_slug)
    area = get_object_or_404(Area, project=project, slug=area_slug)
    contractor = get_object_or_404(Contractor, project=project,
                                   slug=contractor_slug)

    if not has_access(request.user, project, contractor):
        raise PermissionDenied()

    fig = ScreenFigure(600, 350)  # in pixels
    fig.text(
        0.5, 0.85,
        ('Uitgevoerde werkzaamheden {contractor}'
         .format(contractor=contractor.organization.name)),
        fontsize=14, ha='center')
    fig.subplots_adjust(left=0.05, right=0.95)  # smaller margins
    y_title = -0.2  # a bit lower

    def autopct(pct):
        "Convert absolute numbers into percentages."
        total = done + todo
        return "%d" % int(round(pct * total / 100.0))

    def subplot_generator(images):
        """Yields matplotlib subplot placing numbers"""

        # Maybe we can make this smarter later on
        rows = 1
        cols = images

        start = 100 * rows + 10 * cols

        n = 0
        while n < images:
            n += 1
            yield start + n

    mtypes = project.measurementtype_set.all()
    subplots = subplot_generator(len(mtypes))

    for mtype in mtypes:
        # Profiles to be measured
        total = (ScheduledMeasurement.objects.
                 filter(project=project,
                        contractor=contractor,
                        measurement_type=mtype,
                        location__area=area).count())

        # Measured profiles
        done = ScheduledMeasurement.objects.filter(project=project,
                                                   contractor=contractor,
                                                   measurement_type=mtype,
                                                   location__area=area,
                                                   complete=True).count()

        todo = total - done
        x = [done, todo]
        labels = ['Wel', 'Niet']
        colors = ['#50CD34', '#FE6535']
        ax = fig.add_subplot(subplots.next())
        ax.pie(x, labels=labels, colors=colors, autopct=autopct)
        ax.set_title(mtype.name, y=y_title)
        ax.set_aspect('equal')  # circle

    # Create the response
    response = http.HttpResponse(content_type='image/png')
    canvas = FigureCanvas(fig)
    canvas.print_png(response)
    return response