def build_installers(self, vessel_list, user_data=None):
    """
    <Purpose>
      Allows XML-RPC clients to build installers.

    <Arguments>
      vessels:
        A list of vessels, each represented by a dictonary. The dictionary
        should contain 'percentage', 'owner', and (optionally) 'users'
        entries.
        
      platforms:
        A list of platforms for which to build the installers, such as
        'linux', 'mac', or 'windows'.
        
      user_data:
        An optional dictionary with user names as keys, and sub-dictionaries
        as values. The sub-dictionaries may contain a 'public_key' entry.

    <Exceptions>
      ValidationError if malformed data was passed.

    <Side Effects>
      Creates the desired installers and writes them to disk.

    <Returns>
      A dictionary which contains the build ID, URLs pointing to the
      newly built installers, and a dictionary of user cryptographic keys.
    """
    
    manager = BuildManager(vessel_list, user_data)
    return manager.prepare()
示例#2
0
def build_installers(request):
  """
  <Purpose>
    Uses the build data from the user's session to build the installers and
    cryptogrpahic key packages. Designed for AJAX use.

  <Arguments>
    request:
      A Django request.

  <Exceptions>
    None.

  <Side Effects>
    The created packages will be written to the appropriate location on disk.

  <Returns>
    A Django response with text indicating success or error.
  """
  
  if 'build_string' not in request.session:
    return ErrorReponse('No build data provided.')
    
  build_data = json.loads(request.session['build_string'])
    
  user_data = {}
    
  for user in build_data['users']:
    user_data[user['name']] = {'public_key': user['public_key']}
    
  try:
    manager = BuildManager(vessel_list=build_data['vessels'], user_data=user_data)
    build_results = manager.prepare()
  except validations.ValidationError, e:
    return ErrorResponse(e.message)
示例#3
0
    def get_urls(self, build_id):
        """
    <Purpose>
      Allows XML-RPC clients request the URLs for builds other than their own.

    <Arguments>
      build_id:
        The build ID of a previously generated custom installer.

    <Exceptions>
      ValidationError if improper build_id is passed.

    <Side Effects>
      None.

    <Returns>
      A dictionary which contains URLs pointing to the installers, and a
      dictionary of user cryptographic keys.
    """

        validations.validate_build_id(build_id)

        manager = BuildManager(build_id=build_id)

        if not os.path.isdir(manager.get_build_directory()):
            raise validations.ValidationError('Given build ID does not exist.')

        return manager.get_urls()
  def get_urls(self, build_id):
    """
    <Purpose>
      Allows XML-RPC clients request the URLs for builds other than their own.

    <Arguments>
      build_id:
        The build ID of a previously generated custom installer.

    <Exceptions>
      ValidationError if improper build_id is passed.

    <Side Effects>
      None.

    <Returns>
      A dictionary which contains URLs pointing to the installers, and a
      dictionary of user cryptographic keys.
    """

    validations.validate_build_id(build_id)

    manager = BuildManager(build_id=build_id)

    if not os.path.isdir(manager.get_build_directory()):
      raise validations.ValidationError('Given build ID does not exist.')

    return manager.get_urls()
示例#5
0
    def build_installers(self, vessel_list, user_data=None):
        """
    <Purpose>
      Allows XML-RPC clients to build installers.

    <Arguments>
      vessels:
        A list of vessels, each represented by a dictonary. The dictionary
        should contain 'percentage', 'owner', and (optionally) 'users'
        entries.
        
      platforms:
        A list of platforms for which to build the installers, such as
        'linux', 'mac', or 'windows'.
        
      user_data:
        An optional dictionary with user names as keys, and sub-dictionaries
        as values. The sub-dictionaries may contain a 'public_key' entry.

    <Exceptions>
      ValidationError if malformed data was passed.

    <Side Effects>
      Creates the desired installers and writes them to disk.

    <Returns>
      A dictionary which contains the build ID, URLs pointing to the
      newly built installers, and a dictionary of user cryptographic keys.
    """

        manager = BuildManager(vessel_list, user_data)
        return manager.prepare()
def download_installers_page(request, build_id):
  """
  <Purpose>
    Renders the installer package download page.
  <Arguments>
    request:
      A Django request.
    build_id:
      The build ID of the results to display.
  <Exceptions>
    None.
  <Side Effects>
    None.
  <Returns>
    A Django response.
  """

  manager = BuildManager(build_id=build_id)

  # Invalid build IDs should results in an error.
  if not os.path.isdir(manager.get_build_directory()):
    raise Http404
    
  # Compile the list of links of where to find the installers and cryptographic
  # key archives.
  installer_links = manager.get_urls()
    
  # If there is a query string appended to the current URL, we don't want that
  # in the share-this-URL box.
  share_url = request.build_absolute_uri().split('?')[0]
  
  # Only show the progress bar if the user has built this installer himself.
  # Otherwise, we assume the user has shared this link with a friend.
  step = None
  user_built = False
  
  if 'build_results' in request.session:
    if build_id in request.session['build_results']:
      step = 'installers'
      user_built = True

      # If we serve a fast_lane_build we don't show the breadcrumbs
      if 'fast_lane_build' in request.session['build_results'][build_id]:
        step = False

  return render(request, 'download_installers.html',
      {
        'build_id': build_id,
        'installers': installer_links,
        'share_url': share_url,
        'step': step,
        'user_built': user_built,
      })
def build_installers(request):
    """
  <Purpose>
    Uses the build data from the user's session to build the installers and
    cryptogrpahic key packages. Designed for AJAX use.

  <Arguments>
    request:
      A Django request.

  <Exceptions>
    None.

  <Side Effects>
    The created packages will be written to the appropriate location on disk.

  <Returns>
    A Django response with text indicating success or error.
  """

    if 'build_string' not in request.session:
        return ErrorReponse('No build data provided.')

    build_data = json.loads(request.session['build_string'])

    user_data = {}

    for user in build_data['users']:
        user_data[user['name']] = {'public_key': user['public_key']}

    try:
        manager = BuildManager(vessel_list=build_data['vessels'],
                               user_data=user_data)
        build_results = manager.prepare()
    except validations.ValidationError as e:
        return ErrorResponse(e)
    except:
        log_exception(request)
        return ErrorResponse(
            'Unknown error occured while trying to build the installers.')
    else:
        # Save the build results so that the download pages can access the information.
        build_id = build_results['build_id']

        if 'build_results' in request.session:
            request.session['build_results'][build_id] = build_results
            request.session.save()
        else:
            request.session['build_results'] = {build_id: build_results}

        return TextResponse(
            reverse('download-keys-page',
                    kwargs={'build_id': manager.build_id}))
def download_installers_page(request, build_id):
    """
  <Purpose>
    Renders the installer package download page.
  <Arguments>
    request:
      A Django request.
    build_id:
      The build ID of the results to display.
  <Exceptions>
    None.
  <Side Effects>
    None.
  <Returns>
    A Django response.
  """

    manager = BuildManager(build_id=build_id)

    # Invalid build IDs should results in an error.
    if not os.path.isdir(manager.get_build_directory()):
        raise Http404

    # Compile the list of links of where to find the installers and cryptographic
    # key archives.
    installer_links = manager.get_urls()

    # If there is a query string appended to the current URL, we don't want that
    # in the share-this-URL box.
    share_url = request.build_absolute_uri().split('?')[0]

    # Only show the progress bar if the user has built this installer himself.
    # Otherwise, we assume the user has shared this link with a friend.
    step = None
    user_built = False

    if 'build_results' in request.session:
        if build_id in request.session['build_results']:
            step = 'installers'
            user_built = True

            # If we serve a fast_lane_build we don't show the breadcrumbs
            if 'fast_lane_build' in request.session['build_results'][build_id]:
                step = False

    return render(
        request, 'download_installers.html', {
            'build_id': build_id,
            'installers': installer_links,
            'share_url': share_url,
            'step': step,
            'user_built': user_built,
        })
def build_installers(request):
  """
  <Purpose>
    Uses the build data from the user's session to build the installers and
    cryptogrpahic key packages. Designed for AJAX use.

  <Arguments>
    request:
      A Django request.

  <Exceptions>
    None.

  <Side Effects>
    The created packages will be written to the appropriate location on disk.

  <Returns>
    A Django response with text indicating success or error.
  """
  
  if 'build_string' not in request.session:
    return ErrorReponse('No build data provided.')
    
  build_data = json.loads(request.session['build_string'])

  user_data = {}
    
  for user in build_data['users']:
    user_data[user['name']] = {'public_key': user['public_key']}
    
  try:
    manager = BuildManager(vessel_list=build_data['vessels'], user_data=user_data)
    build_results = manager.prepare()
  except validations.ValidationError as e:
    return ErrorResponse(e)
  except:
    log_exception(request)
    return ErrorResponse('Unknown error occured while trying to build the installers.')
  else:
    # Save the build results so that the download pages can access the information.
    build_id = build_results['build_id']
    
    if 'build_results' in request.session:
      request.session['build_results'][build_id] = build_results
      request.session.save()
    else:
      request.session['build_results'] = {build_id: build_results}
    
    return TextResponse(reverse('download-keys-page', kwargs={'build_id': manager.build_id}))
def download_keys(request, build_id, key_type):
    """
  <Purpose>
    Initiates a download of a key bundle.
  <Arguments>
    request:
      A Django request.
    build_id:
      The build ID of the file to download.
    key_type:
      The type of key bundle to return ('public' or 'private').
  <Exceptions>
    None.
  <Side Effects>
    None.
  <Returns>
    A Django response which initiates a download through a redirect.
  """

    manager = BuildManager(build_id=build_id)

    # Invalid build IDs should results in an error.
    if not os.path.isdir(manager.get_build_directory()):
        raise Http404

    key_filenames = packager.package_keys(
        request.session['build_results'][build_id]['users'])

    # Generally, it is undesirable to serve files directly through django, but
    # the key bundles should be very small and still download quickly.
    bundle_filename = key_filenames[key_type]
    # FileResponse is a subclass of StreamingHttpResponse optimized
    # for binary files requires  Django >1.8
    response = FileResponse(open(bundle_filename),
                            content_type='application/zip')
    response['Content-Disposition'] = 'attachment; filename=' + os.path.split(
        bundle_filename)[1]
    response['Content-Length'] = os.path.getsize(bundle_filename)

    # The HTML form will not give access to the installers until the user has
    # downloaded the private keys.
    keys_downloaded = request.session['build_results'][build_id].get(
        'keys_downloaded', dict())
    keys_downloaded[key_type] = True
    request.session['build_results'][build_id][
        'keys_downloaded'] = keys_downloaded
    request.session.save()

    return response
示例#11
0
def download_installer(request, build_id, platform):
  """
  <Purpose>
    Initiates a download of an installer.
  <Arguments>
    request:
      A Django request.
    build_id:
      The build ID of the file to download.
    platform:
      The platform for which to build the installer.
  <Exceptions>
    None.
  <Side Effects>
    None.
  <Returns>
    A Django response which initiates a download through a redirect.
  """
  
  manager = BuildManager(build_id=build_id)

  # Invalid build IDs should results in an error.
  if not os.path.isdir(manager.get_build_directory()):
    raise Http404

  if not manager.installer_exists(platform):
    manager.package(platform)

  installer_url = manager.get_static_urls()[platform]
  return HttpResponseRedirect(installer_url)
def download_keys(request, build_id, key_type):
  """
  <Purpose>
    Initiates a download of a key bundle.
  <Arguments>
    request:
      A Django request.
    build_id:
      The build ID of the file to download.
    key_type:
      The type of key bundle to return ('public' or 'private').
  <Exceptions>
    None.
  <Side Effects>
    None.
  <Returns>
    A Django response which initiates a download through a redirect.
  """
  
  manager = BuildManager(build_id=build_id)

  # Invalid build IDs should results in an error.
  if not os.path.isdir(manager.get_build_directory()):
    raise Http404

  key_filenames = packager.package_keys(request.session['build_results'][build_id]['users'])

  # Generally, it is undesirable to serve files directly through django, but
  # the key bundles should be very small and still download quickly.
  bundle_filename = key_filenames[key_type]
  # FileResponse is a subclass of StreamingHttpResponse optimized
  # for binary files requires  Django >1.8
  response = FileResponse(open(bundle_filename), content_type='application/zip')
  response['Content-Disposition'] = 'attachment; filename=' + os.path.split(bundle_filename)[1]
  response['Content-Length'] = os.path.getsize(bundle_filename)
  
  # The HTML form will not give access to the installers until the user has
  # downloaded the private keys.
  keys_downloaded = request.session['build_results'][build_id].get('keys_downloaded', dict())
  keys_downloaded[key_type] = True
  request.session['build_results'][build_id]['keys_downloaded'] = keys_downloaded
  request.session.save()

  return response
def download_installer(request, build_id, platform):
  """
  <Purpose>
    Initiates a download of an installer.
  <Arguments>
    request:
      A Django request.
    build_id:
      The build ID of the file to download.
    platform:
      The platform for which to build the installer.
  <Exceptions>
    None.
  <Side Effects>
    None.
  <Returns>
    A Django response which initiates a download through a redirect.
  """
  
  manager = BuildManager(build_id=build_id)

  # Invalid build IDs should results in an error.
  if not os.path.isdir(manager.get_build_directory()):
    raise Http404

  if not manager.installer_exists(platform):
    manager.package(platform)

  installer_url = manager.get_static_urls()[platform]
  return HttpResponseRedirect(installer_url)
def fastlane_page(request):
  """
  <Purpose>
    Renders a key and installer download page for a
    default user-built seattle build, i.e.:
      One 80 per-cent vessel, one owner/user

      Note: 
      owner/user-name can be set in settings.FASTLANE_USER_NAME
  <Arguments>
    request:
      A Django request.
  <Exceptions>
    None.
  <Side Effects>
    If new session
    - Creates and stores vesselinfo to appropriate location on disk
    - Stores generated key pair to session (memory)
  <Returns>
    A Django response.
  """

  try:
    existing_build_result = False

    # We have to check if the user already has a build result in his session
    # and make sure it's a fastlane build, i.e.
    # it does not collide with a build from the interactive CIB
    if 'build_results' in request.session.keys():
      for val in request.session['build_results'].values():
        if isinstance(val, dict) and val.get("fast_lane_build"):
          existing_build_result = val
          break
    else:
      # This dict will only be saved if the build succeeds
      request.session['build_results'] = {}


    if existing_build_result:
      # There is no need to build again, let's serve what's already there
      build_id = existing_build_result.get('build_id')
      keys_downloaded = existing_build_result.get('keys_downloaded', dict())

      # The manager helps us to find the files stored to disk
      manager = BuildManager(build_id=build_id)
      installer_links = manager.get_urls()

    else:
      # The user is here for the first time
      # Create basic installation setup (1 owner, 1 vessel, no users)
      users = {
        settings.FASTLANE_USER_NAME: {u'public_key': None}
        }
      vessels = [
        {
          u'owner': settings.FASTLANE_USER_NAME, 
          u'percentage': 80, 
          u'users': []
        }
      ]
      
      # Use build manager to create and store vesselinfo
      # and create cryptographic key pair (only stored in memory)
      manager = BuildManager(vessel_list=vessels, user_data=users)
      new_fastlane_build_results = manager.prepare()

      # These are needed in the HTML template to render the proper links
      # to the keys and installer
      build_id = manager.build_id
      installer_links = manager.get_urls()

      # Used in template to display check marks next to buttons
      # The keys are new so they cannot have been downloaded
      keys_downloaded = False

      # This prevents collision when using interactive CIB and fastlane CIB
      # in the same session
      # also hides breadcrumbs when serving shared (w/o key links) fastlane 
      # download page
      new_fastlane_build_results["fast_lane_build"] = True

      # download_installer and download_keys views get the build_results
      # from the session to serve the correct files
      request.session['build_results'][build_id] = new_fastlane_build_results
      request.session.save()

  except:
    log_exception(request)
    return ErrorResponse('Unknown error occured while' + \
                         ' trying to build the installers.')

  # Builds share_url by using view URLreversing and the request object
  share_url = request.build_absolute_uri(reverse('download-installers-page', 
      args=[build_id]))


  return render(request, 'download_installers.html', {
      'fast_lane': True,
      'build_id': build_id,
      'installers': installer_links,
      'share_url': share_url,
      'keys_downloaded': keys_downloaded,
    })
def fastlane_page(request):
    """
  <Purpose>
    Renders a key and installer download page for a
    default user-built seattle build, i.e.:
      One 80 per-cent vessel, one owner/user

      Note: 
      owner/user-name can be set in settings.FASTLANE_USER_NAME
  <Arguments>
    request:
      A Django request.
  <Exceptions>
    None.
  <Side Effects>
    If new session
    - Creates and stores vesselinfo to appropriate location on disk
    - Stores generated key pair to session (memory)
  <Returns>
    A Django response.
  """

    try:
        existing_build_result = False

        # We have to check if the user already has a build result in his session
        # and make sure it's a fastlane build, i.e.
        # it does not collide with a build from the interactive CIB
        if 'build_results' in request.session.keys():
            for val in request.session['build_results'].values():
                if isinstance(val, dict) and val.get("fast_lane_build"):
                    existing_build_result = val
                    break
        else:
            # This dict will only be saved if the build succeeds
            request.session['build_results'] = {}

        if existing_build_result:
            # There is no need to build again, let's serve what's already there
            build_id = existing_build_result.get('build_id')
            keys_downloaded = existing_build_result.get(
                'keys_downloaded', dict())

            # The manager helps us to find the files stored to disk
            manager = BuildManager(build_id=build_id)
            installer_links = manager.get_urls()

        else:
            # The user is here for the first time
            # Create basic installation setup (1 owner, 1 vessel, no users)
            users = {settings.FASTLANE_USER_NAME: {u'public_key': None}}
            vessels = [{
                u'owner': settings.FASTLANE_USER_NAME,
                u'percentage': 80,
                u'users': []
            }]

            # Use build manager to create and store vesselinfo
            # and create cryptographic key pair (only stored in memory)
            manager = BuildManager(vessel_list=vessels, user_data=users)
            new_fastlane_build_results = manager.prepare()

            # These are needed in the HTML template to render the proper links
            # to the keys and installer
            build_id = manager.build_id
            installer_links = manager.get_urls()

            # Used in template to display check marks next to buttons
            # The keys are new so they cannot have been downloaded
            keys_downloaded = False

            # This prevents collision when using interactive CIB and fastlane CIB
            # in the same session
            # also hides breadcrumbs when serving shared (w/o key links) fastlane
            # download page
            new_fastlane_build_results["fast_lane_build"] = True

            # download_installer and download_keys views get the build_results
            # from the session to serve the correct files
            request.session['build_results'][
                build_id] = new_fastlane_build_results
            request.session.save()

    except:
        log_exception(request)
        return ErrorResponse('Unknown error occured while' + \
                             ' trying to build the installers.')

    # Builds share_url by using view URLreversing and the request object
    share_url = request.build_absolute_uri(
        reverse('download-installers-page', args=[build_id]))

    return render(
        request, 'download_installers.html', {
            'fast_lane': True,
            'build_id': build_id,
            'installers': installer_links,
            'share_url': share_url,
            'keys_downloaded': keys_downloaded,
        })