class Puppetfactory

Public Class Methods

new(app=nil) click to toggle source
Calls superclass method
# File lib/puppetfactory.rb, line 41
  def initialize(app=nil)
    super(app)

    # lets us pretend that the settings object is a hash in our plugins
    def settings.[](opt)
      settings.send(opt) if settings.respond_to? opt
    end

    # Add a link back to the server so that plugins can add routes
    def settings.puppetfactory
      self
    end

    @loaded_plugins = settings.plugins.map do |plugin|
      require "puppetfactory/plugins/#{plugin.snake_case}"
      Puppetfactory::Plugins::const_get(plugin).new(settings)
    end
    @loaded_plugins = @loaded_plugins.sort_by { |plugin| plugin.weight }

    ensure_single_action(:users)
    ensure_single_action(:login)
#    ensure_single_action(:deploy) # TODO: maybe this shouldn't be limited like this.
                                  #       But if not, we need a plugin.suitability() method.
  end

Public Instance Methods

action_enabled?(action) click to toggle source
# File lib/puppetfactory.rb, line 245
def action_enabled?(action)
  resp = @loaded_plugins.select { |plugin| plugin.respond_to? action }
  resp.size != 0
end
authorized?() click to toggle source
# File lib/puppetfactory.rb, line 320
def authorized?
  @auth ||=  Rack::Auth::Basic::Request.new(request.env)

  if @auth.provided? && @auth.basic? && @auth.credentials == [settings.user, settings.password]
    session[:privileges] = 'admin'
    true
  else
    remove_privileges!
    false
  end
end
confined!() click to toggle source
# File lib/puppetfactory.rb, line 310
def confined!
  unless params[:session] == settings.session
    throw(:halt, [403, "Only classroom members are allowed to create accounts!\n"])
  end
end
create(username, password = 'puppetlabs') click to toggle source
# File lib/puppetfactory.rb, line 260
def create(username, password = 'puppetlabs')
  begin
    responses = plugins(:create, username, password)
    errors    = responses.select { |response| response == false }.size

    if errors == 0
      { :status => :success, :message => "Created user #{username}."}.to_json
    else
      # TODO: should we call delete to cleanup?
      #plugins(:delete, username) # Don't leave artifacts.
      { :status => :failure, :message => "There were #{errors} errors creating #{username}. See logs for details."}.to_json
    end
  rescue => e
    $logger.warn e.backtrace
    {:status => :failure, :message => "Fatal error creating #{username}: #{e.message}"}.to_json
  end
end
delete(username) click to toggle source
# File lib/puppetfactory.rb, line 278
def delete(username)
  begin
    responses = reversedplugins(:delete, username)
    errors    = responses.select { |response| response == false }.size

    if errors == 0
      { :status => :success, :message => "Deleted user #{username}."}.to_json
    else
      { :status => :failure, :message => "There were #{errors} errors deleting #{username}. See logs for details."}.to_json
    end
  rescue => e
      {:status => :failure, :message => "Fatal error deleting #{username}: #{e.message}"}.to_json
  end
end
ensure_single_action(action) click to toggle source
# File lib/puppetfactory.rb, line 239
def ensure_single_action(action)
  resp = @loaded_plugins.select { |plugin| plugin.respond_to? action }
  raise "The #{action} action is not exposed by any plugins" if resp.size == 0
  raise "The #{action} action is exposed by multiple loaded plugins! (#{resp.map {|p| p.class }})" unless resp.size == 1
end
load_users(extended = false) click to toggle source
# File lib/puppetfactory.rb, line 293
def load_users(extended = false)
  users = {}
  plugins(:users).flatten.each do |username|
    users[username] = merge(plugins(:userinfo, username, extended))
  end
  users
end
merge(elements) click to toggle source

Take an array of hashes and squash them into a single hash. Keys later in the list override those which come earlier

# File lib/puppetfactory.rb, line 252
def merge(elements)
  elements.inject({}) do |memo, element|
      memo.merge! element
  end
end
plugin(name, action, *args) click to toggle source

call a method of a single named plugin.

# File lib/puppetfactory.rb, line 216
def plugin(name, action, *args)
  plugin = @loaded_plugins.find {|plugin| plugin.class.name == "Puppetfactory::Plugins::#{name.to_s}" }
  plugin.send(action, *args)
end
plugins(action, *args) click to toggle source

call a method on all plugins that implement it

# File lib/puppetfactory.rb, line 222
def plugins(action, *args)
  @loaded_plugins.map do |plugin|
    next unless plugin.respond_to? action

    plugin.send(action, *args)
  end.compact
end
privileged?() click to toggle source
# File lib/puppetfactory.rb, line 316
def privileged?
  session[:privileges] == 'admin'
end
protected!() click to toggle source

Basic auth boilerplate

# File lib/puppetfactory.rb, line 303
def protected!
  unless authorized?
    response['WWW-Authenticate'] = %(Basic realm="Restricted Area")
    throw(:halt, [401, "Not authorized\n"])
  end
end
remove_privileges!() click to toggle source
# File lib/puppetfactory.rb, line 332
def remove_privileges!
  session.delete :privileges
end
reversedplugins(action, *args) click to toggle source

call a method on all plugins that implement it

# File lib/puppetfactory.rb, line 231
def reversedplugins(action, *args)
  @loaded_plugins.reverse.map do |plugin|
    next unless plugin.respond_to? action

    plugin.send(action, *args)
  end.compact
end