Esempio n. 1
0
  def post(self, filename=None):
    """POST handler."""
    if not auth.HasPermission(auth.UPLOAD):
      self.error(403)
      self.response.out.write('Access Denied for current user')
      return

    xsrf_token = self.request.get('xsrf_token', None)
    report_type = filename and 'package' or 'packages'
    if not xsrf.XsrfTokenValidate(xsrf_token, report_type):
      self.error(400)
      self.Render(
          'error.html',
          {'message': 'Invalid XSRF token. Please refresh and retry.'})
      return

    if filename:
      filename = urllib.unquote(filename)

      # If we're updating from new plist xml, perform the update and return.
      if self.request.get('new_pkginfo_plist'):
        self.UpdatePackageInfoFromPlist()
        return

      # All non-plist updates require an existing PackageInfo entity.
      p = models.PackageInfo.get_by_key_name(filename)
      if not p:
        self.error(404)
        self.Render(
            'error.html', {'message': 'PackageInfo not found: %s' % filename})
        return

      if self.request.get('delete') == '1':
        self._DeletePackage(p, filename)

      elif self.request.get('submit', None) == 'save':
        self.UpdatePackageInfo(p)

      elif self.request.get('unlock') == '1':
        self._UnlockPackage(p, filename)

      elif self.request.get('approve') == '1':
        if p.proposal.proposal_in_flight:
          self._ApproveProposal(p, filename)

      elif self.request.get('reject') == '1':
        if p.proposal.proposal_in_flight:
          self._RejectProposal(p, filename)

      else:
        self.error(400)
        self.Render(
            'error.html', {'message': 'No action specified or unknown action.'})

    elif self.request.get('new_pkginfo_plist'):
      # No filename was specified, so we're creating a new PackageInfo.
      self.UpdatePackageInfoFromPlist(create_new=True)
    else:
      self.error(404)
Esempio n. 2
0
  def get(self):
    """GET Handler.

    With no parameters, return the URL to use to submit uploads via
    multipart/form-data.

    With mode and key parameters, return status of the previous uploadpkg
    operation to the calling client.

    This method actually acts as a helper to the starting and finishing
    of the uploadpkg post() method.

    Parameters:
      mode: optionally, 'success' or 'error'
      key: optionally, blobstore key that was uploaded
    """
    if not handlers.IsHttps(self):
      # TODO(user): Does blobstore support https yet? If so, we can
      # enforce security in app.yaml and not do this check here.
      return

    if not auth.HasPermission(auth.UPLOAD):
      self.error(403)
      return

    mode = self.request.get('mode')
    msg = self.request.get('msg', None)
    if mode == 'success':
      filename = self.request.get('filename')
      msg = '%s successfully uploaded and is ready for deployment.' % filename
      self.redirect('/admin/package/%s?msg=%s' % (filename, msg))
    elif mode == 'error':
      self.response.set_status(400)
      self.response.out.write(msg)
    else:
      filename = self.request.get('filename')
      if not filename:
        self.response.set_status(404)
        self.response.out.write('Filename required')
        return

      p = models.PackageInfo.get_by_key_name(filename)
      if not p:
        self.response.set_status(400)
        self.response.out.write(
            'You must first upload a pkginfo for %s' % filename)
        return
      elif p.blob_info:
        self.response.set_status(400)
        self.response.out.write('This file already exists.')
        return

      values = {
          'upload_url': blobstore.create_upload_url(
              '/admin/uploadpkg', gs_bucket_name=util.GetBlobstoreGSBucket()),
          'filename': filename,
          'file_size_kbytes': p.plist['installer_item_size'],
      }
      self.Render('upload_pkg_form.html', values)
Esempio n. 3
0
    def _DisplayPackagesList(self):
        """Displays list of all installs/removals/etc."""
        installs, counts_mtime = models.ReportsCache.GetInstallCounts()
        pending, pending_mtime = models.ReportsCache.GetPendingCounts()
        packages = []
        all_packages = self.request.get('all_packages') == '1'
        query = self._GetPackageQuery()
        for p in query:
            if not p.plist:
                self.error(httplib.FORBIDDEN)
                self.response.out.write('Package %s has a broken plist!' %
                                        p.filename)
                return
            pkg = {}
            pkg['count'] = installs.get(p.munki_name,
                                        {}).get('install_count', 'N/A')
            pkg['fail_count'] = installs.get(p.munki_name,
                                             {}).get('install_fail_count',
                                                     'N/A')
            pkg['pending_count'] = pending.get(p.munki_name, 'N/A')
            pkg['duration_seconds_avg'] = installs.get(p.munki_name, {}).get(
                'duration_seconds_avg', None) or 'N/A'
            pkg['unattended'] = p.plist.get('unattended_install', False)
            pkg['unattended_uninstall'] = p.plist.get('unattended_uninstall',
                                                      False)
            force_install_after_date = p.plist.get('force_install_after_date',
                                                   None)
            if force_install_after_date:
                pkg['force_install_after_date'] = force_install_after_date
            pkg['catalogs'] = p.catalog_matrix
            pkg['manifests'] = p.manifest_matrix
            pkg['munki_name'] = p.munki_name or p.plist.GetMunkiName()
            pkg['filename'] = p.filename
            pkg['file_size'] = p.plist.get('installer_item_size', 0) * 1024
            pkg['install_types'] = p.install_types
            pkg['manifest_mod_access'] = p.manifest_mod_access
            pkg['description'] = p.description
            pkg['plist_is_signed'] = p.plist_is_signed()
            packages.append(pkg)

        packages.sort(key=lambda pkg: pkg['munki_name'].lower())

        self.Render(
            self.TEMPLATE, {
                'packages': packages,
                'counts_mtime': counts_mtime,
                'pending_mtime': pending_mtime,
                'report_type': self.REPORT_TYPE,
                'active_pkg': self.request.GET.get('activepkg'),
                'is_support_user': auth.IsSupportUser(),
                'can_upload': auth.HasPermission(auth.UPLOAD),
                'is_admin': auth.IsAdminUser(),
                'all_packages': all_packages,
            })
Esempio n. 4
0
    def get(self, filename=None):
        """GET handler."""
        if not filename:
            self.error(httplib.NOT_FOUND)
            return
        elif not auth.HasPermission(auth.VIEW_PACKAGES):
            self.error(httplib.FORBIDDEN)
            return

        filename = urllib.unquote(filename)
        p = models.PackageInfo.get_by_key_name(filename)
        if not p:
            self.error(httplib.NOT_FOUND)
            self.Render('error.html',
                        {'message': 'PackageInfo not found: %s' % filename})
            return

        p.name = p.plist['name']
        p.display_name = p.plist.get('display_name', '')
        p.unattended = p.plist.get('unattended_install')
        p.unattended_uninstall = p.plist.get('unattended_uninstall')
        p.version = p.plist['version']
        force_install_after_date = p.plist.get('force_install_after_date',
                                               None)
        if force_install_after_date:
            p.force_install_after_date = datetime.datetime.strftime(
                force_install_after_date, '%Y-%m-%d')
            p.force_install_after_date_time = datetime.datetime.strftime(
                force_install_after_date, '%H:%M')

        if self.request.referrer and self.request.referrer.endswith(
                'proposals'):
            return_address = '/admin/proposals'
            return_title = 'proposals'
        else:
            return_address = '/admin/packages'
            return_title = 'package'

        if self.request.get('plist_xml'):
            self.Render(
                'plist.html', {
                    'report_type': 'packages',
                    'plist_type': 'package_plist',
                    'xml': admin.XmlToHtml(p.plist.GetXml()),
                    'title': 'Plist for %s' % p.name,
                    'raw_xml_link': '/pkgsinfo/%s' % filename,
                })
        else:
            categories = ([
                x.strip() for x in settings.LIST_OF_CATEGORIES.split(',') if x
            ])
            manifests_and_catalogs_unlocked = (
                p.blob_info or p.plist.get('PackageCompleteURL'))
            data = {
                'pkg': p,
                'report_type': 'package',
                'tracks': common.TRACKS,
                'install_types': common.INSTALL_TYPES,
                'manifest_mod_groups': common.MANIFEST_MOD_GROUPS,
                'approval_required': settings.APPROVAL_REQUIRED,
                'is_admin_user': self.IsAdminUser(),
                'is_support_user': auth.IsSupportUser(),
                'pkg_safe_to_modify': p.IsSafeToModify(),
                'editxml': self.request.get('editxml'),
                'manifests_and_catalogs_unlocked':
                manifests_and_catalogs_unlocked,
                'return_address': return_address,
                'return_title': return_title,
                'categories': categories
            }

            self.Render('package.html', data)