summaryrefslogtreecommitdiff
path: root/packages/chef-server/app
diff options
context:
space:
mode:
Diffstat (limited to 'packages/chef-server/app')
-rw-r--r--packages/chef-server/app/controllers/application.rb67
-rw-r--r--packages/chef-server/app/controllers/nodes.rb48
-rw-r--r--packages/chef-server/app/controllers/openid_consumer.rb68
-rw-r--r--packages/chef-server/app/controllers/openid_register.rb91
-rw-r--r--packages/chef-server/app/controllers/openid_server.rb91
-rw-r--r--packages/chef-server/app/helpers/openid_server_helpers.rb2
-rw-r--r--packages/chef-server/app/views/layout/application.html.haml17
-rw-r--r--packages/chef-server/app/views/nodes/index.html.haml4
-rw-r--r--packages/chef-server/app/views/openid_consumer/start.html.haml (renamed from packages/chef-server/app/views/openid_consumer/start.htmlhaml)0
-rw-r--r--packages/chef-server/app/views/openid_register/index.html.haml15
-rw-r--r--packages/chef-server/app/views/openid_register/show.html.haml5
-rw-r--r--packages/chef-server/app/views/openid_server/decide.html.haml12
12 files changed, 263 insertions, 157 deletions
diff --git a/packages/chef-server/app/controllers/application.rb b/packages/chef-server/app/controllers/application.rb
index 5ce39a0102..4a0d247306 100644
--- a/packages/chef-server/app/controllers/application.rb
+++ b/packages/chef-server/app/controllers/application.rb
@@ -1,2 +1,69 @@
class Application < Merb::Controller
+
+ def fix_up_node_id
+ if params.has_key?(:id)
+ params[:id].gsub!(/_/, '.')
+ end
+ end
+
+ def escape_node_id
+ if params.has_key?(:id)
+ params[:id].gsub(/_/, '.')
+ end
+ end
+
+ def login_required
+ if session[:openid]
+ return session[:openid]
+ else
+ self.store_location
+ throw(:halt, :access_denied)
+ end
+ end
+
+ def authorized_node
+ if session[:level] == :admin
+ Chef::Log.debug("Authorized as Administrator")
+ true
+ elsif session[:level] == :node
+ Chef::Log.debug("Authorized as node")
+ if session[:node_name] == params[:id].gsub(/\./, '_')
+ true
+ else
+ raise(
+ Unauthorized,
+ "You are not the correct node for this action: #{session[:node_name]} instead of #{params[:id]}"
+ )
+ end
+ else
+ Chef::Log.debug("Unauthorized")
+ raise Unauthorized, "You are not allowed to take this action."
+ end
+ end
+
+ # Store the URI of the current request in the session.
+ #
+ # We can return to this location by calling #redirect_back_or_default.
+ def store_location
+ session[:return_to] = request.uri
+ end
+
+ # Redirect to the URI stored by the most recent store_location call or
+ # to the passed default.
+ def redirect_back_or_default(default)
+ loc = session[:return_to] || default
+ session[:return_to] = nil
+ redirect loc
+ end
+
+ def access_denied
+ case content_type
+ when :html
+ store_location
+ redirect url(:openid_consumer)
+ else
+ raise Unauthorized, "You must authenticate first!"
+ end
+ end
+
end \ No newline at end of file
diff --git a/packages/chef-server/app/controllers/nodes.rb b/packages/chef-server/app/controllers/nodes.rb
index 340a981899..aa7273c47d 100644
--- a/packages/chef-server/app/controllers/nodes.rb
+++ b/packages/chef-server/app/controllers/nodes.rb
@@ -3,27 +3,28 @@ class Nodes < Application
provides :html, :json
before :fix_up_node_id
+ before :login_required, :only => [ :create, :update, :destroy ]
+ before :authorized_node, :only => [ :update, :destroy ]
def index
- @node_list = Chef::FileStore.list("node")
+ @node_list = Chef::Node.list
display @node_list
end
def show
begin
- @node = Chef::FileStore.load("node", params[:id])
- rescue RuntimeError => e
- raise BadRequest, "Cannot load node #{params[:id]}"
+ @node = Chef::Node.load(params[:id])
+ rescue Net::HTTPServerException => e
+ raise NotFound, "Cannot load node #{params[:id]}"
end
display @node
end
def create
- @node = params.has_key?("inflated_object") ? params["inflated_object"] : nil
+ @node = params.has_key?("inflated_object") ? params["inflated_object"] : nil
if @node
@status = 202
- Chef::FileStore.store("node", @node.name, @node)
- Chef::Queue.send_msg(:queue, :node_index, @node)
+ @node.save
display @node
else
raise BadRequest, "You must provide a Node to create"
@@ -34,40 +35,33 @@ class Nodes < Application
@node = params.has_key?("inflated_object") ? params["inflated_object"] : nil
if @node
@status = 202
- Chef::FileStore.store("node", @node.name, @node)
- Chef::Queue.send_msg(:queue, :node_index, @node)
+ @node.save
display @node
else
- raise BadRequest, "You must provide a Node to update"
+ raise NotFound, "You must provide a Node to update"
end
end
def destroy
begin
- @node = Chef::FileStore.load("node", params[:id])
+ @node = Chef::Node.load(params[:id])
rescue RuntimeError => e
raise BadRequest, "Node #{params[:id]} does not exist to destroy!"
end
@status = 202
- Chef::FileStore.delete("node", params[:id])
- Chef::Queue.send_msg(:queue, :node_remove, @node)
- display @node
+ @node.destroy
+ if content_type == :html
+ redirect url(:nodes)
+ else
+ display @node
+ end
end
def compile
# Grab a Chef::Compile object
compile = Chef::Compile.new()
compile.load_node(params[:id])
-
- stored_node = Chef::FileStore.load("node", params[:id])
-
- stored_node.each_attribute do |field, value|
- compile.node[field] = value
- end
- stored_node.recipes.each do |r|
- compile.node.recipes << r unless compile.node.recipes.detect { |h| r == h }
- end
- Chef::FileStore.store("node", params[:id], compile.node)
+ compile.node.save
compile.load_definitions
compile.load_recipes
@output = {
@@ -77,10 +71,4 @@ class Nodes < Application
display @output
end
- def fix_up_node_id
- if params.has_key?(:id)
- params[:id].gsub!(/_/, '.')
- end
- end
-
end
diff --git a/packages/chef-server/app/controllers/openid_consumer.rb b/packages/chef-server/app/controllers/openid_consumer.rb
index 58f18445e1..1c8b76296c 100644
--- a/packages/chef-server/app/controllers/openid_consumer.rb
+++ b/packages/chef-server/app/controllers/openid_consumer.rb
@@ -5,16 +5,18 @@ require 'openid/store/filesystem'
class OpenidConsumer < Application
+ provides :html, :json
+
def index
render
end
def start
+ check_valid_openid_provider(params[:openid_identifier])
begin
oidreq = consumer.begin(params[:openid_identifier])
rescue OpenID::OpenIDError => e
- session[:error] = "Discovery failed for #{params[:openid_identifier]}: #{e}"
- return redirect(url(:openid_consumer))
+ raise BadRequest, "Discovery failed for #{params[:openid_identifier]}: #{e}"
end
return_to = absolute_url(:openid_consumer_complete)
realm = absolute_url(:openid_consumer)
@@ -33,26 +35,58 @@ class OpenidConsumer < Application
parameters = params.reject{|k,v| k == "controller" || k == "action"}
oidresp = consumer.complete(parameters, current_url)
case oidresp.status
- when OpenID::Consumer::FAILURE
- if oidresp.display_identifier
- session[:error] = ("Verification of #{oidresp.display_identifier}"\
- " failed: #{oidresp.message}")
+ when OpenID::Consumer::FAILURE
+ if oidresp.display_identifier
+ raise BadRequest, "Verification of #{oidresp.display_identifier} failed: #{oidresp.message}"
+ else
+ raise BadRequest, "Verification failed: #{oidresp.message}"
+ end
+ when OpenID::Consumer::SUCCESS
+ session[:openid] = oidresp.identity_url
+ if oidresp.display_identifier =~ /openid\/server\/node\/(.+)$/
+ session[:level] = :node
+ session[:node_name] = $1
+ else
+ session[:level] = :admin
+ end
+ redirect_back_or_default(absolute_url(:nodes))
+ return "Verification of #{oidresp.display_identifier} succeeded."
+ when OpenID::Consumer::SETUP_NEEDED
+ return "Immediate request failed - Setup Needed"
+ when OpenID::Consumer::CANCEL
+ return "OpenID transaction cancelled."
else
- session[:error] = "Verification failed: #{oidresp.message}"
- end
- when OpenID::Consumer::SUCCESS
- session[:success] = ("Verification of #{oidresp.display_identifier}"\
- " succeeded.")
- when OpenID::Consumer::SETUP_NEEDED
- session[:alert] = "Immediate request failed - Setup Needed"
- when OpenID::Consumer::CANCEL
- session[:alert] = "OpenID transaction cancelled."
- else
end
- redirect url(:openid_consumer)
+ redirect absolute_url(:openid_consumer)
+ end
+
+ def logout
+ session[:openid] = nil if session.has_key?(:openid)
+ session[:level] = nil if session.has_key?(:level)
+ session[:node_name] = nil if session.has_key?(:node_name)
+ redirect url(:top)
end
private
+
+ # Returns true if the openid is at a valid provider, based on whether :openid_providers is
+ # defined. Raises an exception if it is not an allowed provider.
+ def check_valid_openid_provider(openid)
+ if Chef::Config[:openid_providers]
+ fp = Chef::Config[:openid_providers].detect do |p|
+ case openid
+ when /^http:\/\/#{p}/, /^#{p}/
+ true
+ else
+ false
+ end
+ end
+ unless fp
+ raise Unauthorized, "Sorry, #{openid} is not an allowed OpenID Provider."
+ end
+ end
+ true
+ end
def consumer
if @consumer.nil?
diff --git a/packages/chef-server/app/controllers/openid_register.rb b/packages/chef-server/app/controllers/openid_register.rb
index 2636524a2d..a6c30c95c5 100644
--- a/packages/chef-server/app/controllers/openid_register.rb
+++ b/packages/chef-server/app/controllers/openid_register.rb
@@ -6,39 +6,40 @@ require 'openid'
class OpenidRegister < Application
provides :html, :json
+
+ before :fix_up_node_id
def index
- @headers['X-XRDS-Location'] = absolute_url(:controller => "server", :action => "idp_xrds")
- @registered_nodes = Chef::FileStore.list("openid_node")
+ @headers['X-XRDS-Location'] = absolute_url(:controller => "openid_server", :action => "idp_xrds")
+ @registered_nodes = Chef::OpenIDRegistration.list(true)
+ Chef::Log.debug(@registered_nodes.inspect)
display @registered_nodes
end
def show
begin
- @registered_node = Chef::FileStore.load("openid_node", params[:id])
- rescue RuntimeError => e
- raise NotFound, "Cannot load node registration for #{params[:id]}"
- end
+ @registered_node = Chef::OpenIDRegistration.load(params[:id])
+ rescue Net::HTTPServerException => e
+ if e.message =~ /^404/
+ raise NotFound, "Cannot load node registration for #{params[:id]}"
+ else
+ raise e
+ end
+ end
+ Merb.logger.debug(@registered_node.inspect)
display @registered_node
end
def create
params.has_key?(:id) or raise BadRequest, "You must provide an id to register"
params.has_key?(:password) or raise BadRequest, "You must provide a password to register"
- if Chef::FileStore.has_key?("openid_node", params[:id])
+ if Chef::OpenIDRegistration.has_key?(params[:id])
raise BadRequest, "You cannot re-register #{params[:id]}!"
end
- salt = generate_salt
- @registered_node = {
- :id => params[:id],
- :salt => salt,
- :password => encrypt_password(salt, params[:password])
- }
- Chef::FileStore.store(
- "openid_node",
- params[:id],
- @registered_node
- )
+ @registered_node = Chef::OpenIDRegistration.new
+ @registered_node.name = params[:id]
+ @registered_node.set_password(params[:password])
+ @registered_node.save
display @registered_node
end
@@ -47,47 +48,27 @@ class OpenidRegister < Application
end
def destroy
- unless Chef::FileStore.has_key?("openid_node", params[:id])
+ begin
+ r = Chef::OpenIDRegistration.load(params[:id])
+ rescue Exception => e
raise BadRequest, "Cannot find the registration for #{params[:id]}"
end
- Chef::FileStore.delete("openid_node", params[:id])
- display({ :message => "Deleted registration for #{params[:id]}"})
- end
-
- def submit
- user = params[:username]
-
- # if we get a user, log them in by putting their username in
- # the session hash.
- unless user.nil?
- session[:username] = user unless user.nil?
- session[:approvals] = []
- session[:notice] = "Your OpenID URL is <b>
- #{url(:controller => "openid_server", :action => "user_page", :username => params[:username])}
- </b><br/><br/>Proceed to step 2 below."
+ r.destroy
+ if content_type == :html
+ redirect url(:registrations)
else
- session[:error] = "Sorry, couldn't log you in. Try again."
+ display({ :message => "Deleted registration for #{params[:id]}"})
end
-
- redirect url(:openid_login)
- end
-
- def logout
- # delete the username from the session hash
- session[:username] = nil
- session[:approvals] = nil
- redirect url(:openid_login)
end
-
- private
- def generate_salt
- salt = Time.now.to_s
- chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
- 1.upto(30) { |i| salt << chars[rand(chars.size-1)] }
- salt
- end
-
- def encrypt_password(salt, password)
- Digest::SHA1.hexdigest("--#{salt}--#{password}--")
+
+ def validate
+ begin
+ r = Chef::OpenIDRegistration.load(params[:id])
+ rescue Exception => e
+ raise BadRequest, "Cannot find the registration for #{params[:id]}"
end
+ r.validated = r.validated ? false : true
+ r.save
+ redirect url(:registrations)
+ end
end
diff --git a/packages/chef-server/app/controllers/openid_server.rb b/packages/chef-server/app/controllers/openid_server.rb
index cfdb4c4169..665af1fb6d 100644
--- a/packages/chef-server/app/controllers/openid_server.rb
+++ b/packages/chef-server/app/controllers/openid_server.rb
@@ -8,18 +8,23 @@ require 'pathname'
require "openid"
require "openid/consumer/discovery"
require 'openid/store/filesystem'
+require 'json'
#end
class OpenidServer < Application
+ provides :html, :json
+
include Merb::OpenidServerHelper
include OpenID::Server
layout nil
+
+ before :fix_up_node_id
def index
-
- oidreq = server.decode_request(params)
+
+ oidreq = server.decode_request(params.reject{|k,v| k == "controller" || k == "action"})
# no openid.mode was given
unless oidreq
@@ -29,21 +34,8 @@ class OpenidServer < Application
oidresp = nil
if oidreq.kind_of?(CheckIDRequest)
-
identity = oidreq.identity
- if oidreq.id_select
- if oidreq.immediate
- oidresp = oidreq.answer(false)
- elsif session[:username].nil?
- # The user hasn't logged in.
- return show_decision_page(oidreq)
- else
- # Else, set the identity to the one the user is using.
- identity = url_for_user
- end
- end
-
if oidresp
nil
elsif self.is_authorized(identity, oidreq.trust_root)
@@ -52,9 +44,14 @@ class OpenidServer < Application
server_url = url :openid_server
oidresp = oidreq.answer(false, server_url)
else
- return show_decision_page(oidreq)
+ if content_type != 'application/json'
+ session[:last_oidreq] = oidreq
+ response = { :action => url(:openid_server_decision) }
+ return response.to_json
+ else
+ return show_decision_page(oidreq)
+ end
end
-
else
oidresp = server.handle_request(oidreq)
end
@@ -73,7 +70,11 @@ class OpenidServer < Application
render :template => 'openid_server/decide'
end
- def user_page
+ def node_page
+ unless Chef::OpenIDRegistration.has_key?(params[:id])
+ raise NotFound, "Cannot find registration for #{params[:id]}"
+ end
+
# Yadis content-negotiation: we want to return the xrds if asked for.
accept = request.env['HTTP_ACCEPT']
@@ -81,16 +82,16 @@ class OpenidServer < Application
# to do real Accept header parsing and logic. Though I expect it will work
# 99% of the time.
if accept and accept.include?('application/xrds+xml')
- return user_xrds
+ return node_xrds
end
# content negotiation failed, so just render the user page
- xrds_url = url(:openid_user_xrds, :username => params[:username])
+ xrds_url = absolute_url(:openid_node_xrds, :id => params[:id])
identity_page = <<EOS
<html><head>
<meta http-equiv="X-XRDS-Location" content="#{xrds_url}" />
-<link rel="openid.server" href="#{absolute_url :openid_user, :username}" />
-</head><body><p>OpenID identity page for #{params[:username]}</p>
+<link rel="openid.server" href="#{absolute_url(:openid_node, :id => params[:id])}" />
+</head><body><p>OpenID identity page for registration #{params[:id]}</p>
</body></html>
EOS
@@ -100,11 +101,10 @@ EOS
render identity_page
end
- def user_xrds
+ def node_xrds
types = [
OpenID::OPENID_2_0_TYPE,
- OpenID::OPENID_1_0_TYPE,
- OpenID::SREG_URI,
+ OpenID::OPENID_1_0_TYPE
]
render_xrds(types)
@@ -122,37 +122,36 @@ EOS
oidreq = session[:last_oidreq]
session[:last_oidreq] = nil
- if params[:yes].nil?
- redirect oidreq.cancel_url
- return
- else
- id_to_send = params[:id_to_send]
-
+ if params.has_key?(:cancel)
+ Merb.logger.info("Cancelling OpenID Authentication")
+ return(redirect(oidreq.cancel_url))
+ else
identity = oidreq.identity
- if oidreq.id_select
- if id_to_send and id_to_send != ""
- session[:username] = id_to_send
- session[:approvals] = []
- identity = url_for_user
+ identity =~ /node\/(.+)$/
+ openid_node = Chef::OpenIDRegistration.load($1)
+ unless openid_node.validated
+ raise Unauthorized, "This nodes registration has not been validated"
+ end
+ if openid_node.password == encrypt_password(openid_node.salt, params[:password])
+ if session[:approvals]
+ session[:approvals] << oidreq.trust_root
else
- msg = "You must enter a username to in order to send " +
- "an identifier to the Relying Party."
- return show_decision_page(oidreq, msg)
+ session[:approvals] = [oidreq.trust_root]
end
- end
-
- if session[:approvals]
- session[:approvals] << oidreq.trust_root
+ oidresp = oidreq.answer(true, nil, identity)
+ return self.render_response(oidresp)
else
- session[:approvals] = [oidreq.trust_root]
+ raise Unauthorized, "Invalid credentials"
end
- oidresp = oidreq.answer(true, nil, identity)
- return self.render_response(oidresp)
end
end
protected
+ def encrypt_password(salt, password)
+ Digest::SHA1.hexdigest("--#{salt}--#{password}--")
+ end
+
def server
if @server.nil?
server_url = absolute_url(:openid_server)
diff --git a/packages/chef-server/app/helpers/openid_server_helpers.rb b/packages/chef-server/app/helpers/openid_server_helpers.rb
index 8e595ead01..73be9cab27 100644
--- a/packages/chef-server/app/helpers/openid_server_helpers.rb
+++ b/packages/chef-server/app/helpers/openid_server_helpers.rb
@@ -2,7 +2,7 @@ module Merb
module OpenidServerHelper
def url_for_user
- url(:openid_user, :username => session[:username])
+ url(:openid_node, :username => session[:username])
end
end
diff --git a/packages/chef-server/app/views/layout/application.html.haml b/packages/chef-server/app/views/layout/application.html.haml
index ea9d378ad4..f04f299d2c 100644
--- a/packages/chef-server/app/views/layout/application.html.haml
+++ b/packages/chef-server/app/views/layout/application.html.haml
@@ -6,10 +6,17 @@
%meta{"http-equiv" => "content-type", :content => "text/html; charset=utf-8" }
%link{:rel => "stylesheet", :href => "/stylesheets/master.css", :type => "text/css", :media => "screen", :charset => "utf-8" }
%body
+ .header
+ %a{:href => url(:nodes) } Nodes
+ |
+ %a{:href => url(:registrations)} Registrations
+ - if session[:openid]
+ |
+ %a{:href => url(:openid_consumer_logout)}= "Logout #{h session[:openid]}"
+ = "(#{session[:level].to_s})"
+ - else
+ |
+ %a{:href => url(:openid_consumer)} Login
= catch_content :for_layout
- .footer
- - if session[:username]
- %a{:href => url(:openid_logout)}= "Log Out #{session[:username]}"
- %br/
- = absolute_url(:openid_user, :username => session[:username])
+
\ No newline at end of file
diff --git a/packages/chef-server/app/views/nodes/index.html.haml b/packages/chef-server/app/views/nodes/index.html.haml
index 908f72fab5..667e1c7317 100644
--- a/packages/chef-server/app/views/nodes/index.html.haml
+++ b/packages/chef-server/app/views/nodes/index.html.haml
@@ -3,3 +3,7 @@
.node
%a{ :href => url(:node, { :id => node.gsub(/\./, "_") }) }
= node
+ %form{ :method => "post", :action => url(:node, { :id => node.gsub(/\./, "_") })}
+ %input{ :type => "hidden", :name => "_method", :value => "delete" }
+ %input{ :type => "submit", :name => "Delete", :value => "Delete" }
+ \ No newline at end of file
diff --git a/packages/chef-server/app/views/openid_consumer/start.htmlhaml b/packages/chef-server/app/views/openid_consumer/start.html.haml
index 75ed9a9257..75ed9a9257 100644
--- a/packages/chef-server/app/views/openid_consumer/start.htmlhaml
+++ b/packages/chef-server/app/views/openid_consumer/start.html.haml
diff --git a/packages/chef-server/app/views/openid_register/index.html.haml b/packages/chef-server/app/views/openid_register/index.html.haml
new file mode 100644
index 0000000000..fe4798c59d
--- /dev/null
+++ b/packages/chef-server/app/views/openid_register/index.html.haml
@@ -0,0 +1,15 @@
+%h1 Registered OpenID Nodes List
+%table
+- @registered_nodes.each do |node|
+ %tr
+ %td
+ %a{ :href => url(:registration, { :id => node.name }) }
+ = h node.name
+ %td
+ - if session[:level] == :admin
+ %form{ :method => "post", :action => url(:validate_registration, { :id => node.name })}
+ - submit_name = node.validated ? "Invalidate" : "Validate"
+ %input{ :type => "submit", :name => submit_name, :value => submit_name }
+ %form{ :method => "post", :action => url(:registration, { :id => node.name })}
+ %input{ :type => "hidden", :name => "_method", :value => "delete" }
+ %input{ :type => "submit", :name => "Delete", :value => "Delete" }
diff --git a/packages/chef-server/app/views/openid_register/show.html.haml b/packages/chef-server/app/views/openid_register/show.html.haml
new file mode 100644
index 0000000000..cfd38e8963
--- /dev/null
+++ b/packages/chef-server/app/views/openid_register/show.html.haml
@@ -0,0 +1,5 @@
+%h1= "Registered OpenID Node #{@registered_node.name}"
+%ol
+ %li
+ %a{ :href => url(:openid_node , { :id => @registered_node.name.gsub(/\./, "_") }) } OpenID URL
+ %li= "Validated: #{@registered_node.validated}"
diff --git a/packages/chef-server/app/views/openid_server/decide.html.haml b/packages/chef-server/app/views/openid_server/decide.html.haml
index 78b0b60881..8082a5068d 100644
--- a/packages/chef-server/app/views/openid_server/decide.html.haml
+++ b/packages/chef-server/app/views/openid_server/decide.html.haml
@@ -8,7 +8,7 @@
%td{:colspan => "2"}
You entered the server identifier at the relying party.
You will need to send an identifier of your choosing.
- Enter a username below.
+ Enter a username and password below.
%tr
%td Identity to send:
%td
@@ -17,5 +17,11 @@
%tr
%td Identity:
%td= @oidreq.identity
- %input{:type => "submit", :name => "yes", :value => "yes"}
- %input{:type => "submit", :name => "no", :value => "no"} \ No newline at end of file
+ %tr
+ %td
+ %label{:for => "password"} Password:
+ %td
+ %input{:type => "password", :name => "password"}
+ %input{:type => "submit", :name => "submit", :value => "Authenticate"}
+ %input{:type => "submit", :name => "cancel", :value => "Cancel"}
+