#!/usr/bin/ruby

require 'cgi'

class Servlet
  CONFIGFILE_PATH = "/tmp"

  #--------------------------------------------------
  # Process CGI request
  def cgi_process_request
    @cgi = CGI.new('html4')

    # Assembla may test if we are alive
    if @cgi['project'].empty?
      cgi_response('OK', 'Configure agent is alive')
    else
      configure()
    end

  end


  #--------------------------------------------------
  # Respond to CGI request
  def cgi_response(code, text = '')
    @cgi.out("status"     => code,
             "type"       => "text/html") {text}
  end


  #--------------------------------------------------
  # Return a public key file name
  def public_key()

    # Use HOME for user home directory if possible.
    # If not, workaround by using SCRIPT_FILENAME
    if ENV['HOME'] != nil && ! ENV['HOME'].empty?
      homedir = "#{ENV['HOME']}"
    else
      owner = `ls -l #{ENV['SCRIPT_FILENAME']} | head -1 | awk '{print $3}'`.chomp
      homedir = `grep ^#{owner} /etc/passwd | awk -F : '{print $6}'`.chomp
    end

    return nil if homedir == nil || homedir.empty?

    # Check for existing dsa key
    dsa_privkey = "#{homedir}/.ssh/id_dsa"
    dsa_pubkey = "#{dsa_privkey}.pub"
    return dsa_pubkey if File.exists?(dsa_privkey) && File.exists?(dsa_pubkey)

    # Check for existing rsa key
    rsa_privkey = "#{homedir}/.ssh/id_rsa"
    rsa_pubkey = "#{rsa_privkey}.pub"
    return rsa_pubkey if File.exists?(rsa_privkey) && File.exists?(rsa_pubkey)

    # Generate and authorize a new dsa key
    `ssh-keygen -q -t dsa -f #{dsa_privkey} -N ''`
    `cat #{dsa_privkey}.pub >> #{homedir}/.ssh/authorized_keys`

    return dsa_pubkey
  end


  #--------------------------------------------------
  # Handle the configure action
  def configure

    configfile = "#{CONFIGFILE_PATH}/#{@cgi['project']}_conf.sh"

    # For security, only allow the configure action to be run once.
    if File.exists?(configfile)
      cgi_response('METHOD_NOT_ALLOWED', "Project #{@cgi['project']} is already configured")
      return
    end

    # The CGI 'config' specifies configuration text as bash variables.
    # Write this text to the config file.
    File.open(configfile, 'w', 0755) do |f|
      f.write(@cgi['config'])
    end

    # Read the user public key
    pubkeyfile = public_key()
    pubkeytext = nil
    if File.readable?(pubkeyfile)
      File.open(pubkeyfile, 'r') do |f|
        break if f.nil?
        pubkeytext = f.read
      end
    end

    # Respond with public key if we have it
    if File.exists?(configfile) 

      if pubkeytext && pubkeytext.length > 0
        cgi_response('OK', pubkeytext)
      else
        cgi_response('OK', 'Config updated successfully')
      end

    else
      cgi_response('METHOD_NOT_ALLOWED', 'config file creation/update failed')
    end

  end

end

Servlet.new.cgi_process_request

