Skip to content

Commit

Permalink
Service ticket validation complete
Browse files Browse the repository at this point in the history
  • Loading branch information
spicycode committed Sep 9, 2008
1 parent 4471ae1 commit f41176f
Show file tree
Hide file tree
Showing 15 changed files with 537 additions and 27 deletions.
5 changes: 2 additions & 3 deletions .autotest
Expand Up @@ -4,8 +4,7 @@ Autotest.add_hook :initialize do |autotest|
# autotest.sleep = 3 # autotest.sleep = 3


# Ignore files with suffix # Ignore files with suffix
%w{.svn .log .hg .git .erb .rhtml .png .txt .sh .project .rjs .rake .jpg .css .xml}.each { |exception| autotest.add_exception(exception) }

%w{.svn .log .hg .git .erb .rhtml .png .txt .sh .project .rjs .rake .jpg .css .xml vendor db}.each { |exception| autotest.add_exception(exception) }
# autotest.add_exception(/^\.\/vendor/)


end end
3 changes: 3 additions & 0 deletions app/controllers/application.rb
Expand Up @@ -21,6 +21,9 @@
end end


get '/serviceValidate' do get '/serviceValidate' do
# @presenter = Castronaut::Presenters::ServiceValidate.new(self)
# @presenter.represent!
# @presenter.your_mission.call
body 'serviceValidate-Get' body 'serviceValidate-Get'
end end


Expand Down
1 change: 1 addition & 0 deletions lib/castronaut.rb
Expand Up @@ -9,6 +9,7 @@
require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'ticket_result')) require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'ticket_result'))
require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'presenters', 'login')) require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'presenters', 'login'))
require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'presenters', 'process_login')) require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'presenters', 'process_login'))
require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'presenters', 'service_validate'))
require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'adapters')) require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'adapters'))
require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'adapters', 'restful_authentication', 'adapter')) require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'adapters', 'restful_authentication', 'adapter'))
require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'adapters', 'restful_authentication', 'user')) require File.expand_path(File.join(File.dirname(__FILE__), 'castronaut', 'adapters', 'restful_authentication', 'user'))
Expand Down
33 changes: 33 additions & 0 deletions lib/castronaut/models/service_ticket.rb
Expand Up @@ -8,6 +8,8 @@ class ServiceTicket < ActiveRecord::Base
include Castronaut::Models::Consumeable include Castronaut::Models::Consumeable
include Castronaut::Models::Dispenser include Castronaut::Models::Dispenser


MissingMessage = "Ticket or service parameter was missing in the request."

belongs_to :ticket_granting_ticket belongs_to :ticket_granting_ticket


before_validation :dispense_ticket, :if => :new_record? before_validation :dispense_ticket, :if => :new_record?
Expand All @@ -19,6 +21,33 @@ def self.generate_ticket_for(service, client_host, ticket_granting_ticket)
:client_hostname => client_host, :client_hostname => client_host,
:ticket_granting_ticket => ticket_granting_ticket :ticket_granting_ticket => ticket_granting_ticket
end end

def self.validate_ticket(service, ticket, allow_proxy_tickets = false)

return Castronaut::TicketResult.new(nil, MissingMessage, "INVALID_REQUEST") unless service && ticket

service_ticket = find_by_ticket(ticket)

return Castronaut::TicketResult.new(nil, "Ticket #{ticket} not recognized.", "INVALID_TICKET") unless service_ticket

return Castronaut::TicketResult.new(service_ticket, "Ticket '#{ticket}' has already been used up.", "INVALID_TICKET") if service_ticket.consumed?

service_ticket.consume!

# if service_ticket.kind_of?(CASServer::Models::ProxyTicket) && !allow_proxy_tickets
# return Castronaut::TicketResult.new(service_ticket, "Ticket '#{ticket}' is a proxy ticket, but only service tickets are allowed here.", "INVALID_TICKET")
# end

return Castronaut::TicketResult.new(service_ticket, "Ticket '#{ticket}' has expired.", "INVALID_TICKET") if service_ticket.expired?

mismatched_service_message = "The ticket '#{ticket}' belonging to user '#{service_ticket.username}' is valid, but the requested service '#{service}' does not match the service '#{service_ticket.service}' associated with this ticket."

return Castronaut::TicketResult.new(service_ticket, mismatched_service_message, "INVALID_SERVICE") unless service_ticket.matches_service?(service)
end

def matches_service?(other_service)
service == other_service
end


def service_uri def service_uri
return nil if service.blank? return nil if service.blank?
Expand Down Expand Up @@ -46,6 +75,10 @@ def ticket_prefix
"ST" "ST"
end end


def expired?
# Time.now - service_ticket.created_on > CASServer::Conf.service_ticket_expiry
end

end end


end end
Expand Down
4 changes: 2 additions & 2 deletions lib/castronaut/models/ticket_granting_ticket.rb
Expand Up @@ -13,13 +13,13 @@ class TicketGrantingTicket < ActiveRecord::Base
def self.validate_cookie(ticket_cookie) def self.validate_cookie(ticket_cookie)
Castronaut.logger.debug("#{self} - Validating ticket for #{ticket_cookie}") Castronaut.logger.debug("#{self} - Validating ticket for #{ticket_cookie}")


return Castronaut::TicketResult.new(nil, "No ticket granting ticket given") if ticket_cookie.nil? return Castronaut::TicketResult.new(nil, "No ticket granting ticket given", 'warn') if ticket_cookie.nil?


ticket_granting_ticket = find_by_ticket(ticket_cookie) ticket_granting_ticket = find_by_ticket(ticket_cookie)


if ticket_granting_ticket if ticket_granting_ticket
Castronaut.logger.debug("#{self} -[#{ticket_cookie}] for [#{ticket_granting_ticket.username}] successfully validated.") Castronaut.logger.debug("#{self} -[#{ticket_cookie}] for [#{ticket_granting_ticket.username}] successfully validated.")
return Castronaut::TicketResult.new(ticket_granting_ticket, "Your session has expired. Please log in again.") if ticket_granting_ticket.expired? return Castronaut::TicketResult.new(ticket_granting_ticket, "Your session has expired. Please log in again.", 'warn') if ticket_granting_ticket.expired?
else else
Castronaut.logger.debug("#{self} - [#{ticket_cookie}] was not found in the database.") Castronaut.logger.debug("#{self} - [#{ticket_cookie}] was not found in the database.")
end end
Expand Down
2 changes: 1 addition & 1 deletion lib/castronaut/presenters/login.rb
Expand Up @@ -48,7 +48,7 @@ def represent!
ticket_granting_ticket_result = Castronaut::Models::TicketGrantingTicket.validate_cookie(ticket_generating_ticket_cookie) ticket_granting_ticket_result = Castronaut::Models::TicketGrantingTicket.validate_cookie(ticket_generating_ticket_cookie)


if ticket_granting_ticket_result.valid? if ticket_granting_ticket_result.valid?
messages << "You are currently logged in as #{ticket_granting_ticket_result.username}. If this is not you, please log in below." messages << "You are currently logged in as #{ticket_granting_ticket_result.username}. If this is not you, please log in below."
end end


if redirection_loop? if redirection_loop?
Expand Down
4 changes: 2 additions & 2 deletions lib/castronaut/presenters/process_login.rb
Expand Up @@ -45,7 +45,7 @@ def client_host
# POSSIBLE SHARED ABOVE # POSSIBLE SHARED ABOVE


def username def username
params['username'].strip params['username'].to_s.strip
end end


def password def password
Expand All @@ -58,7 +58,7 @@ def represent!
login_ticket_validation_result = Castronaut::Models::LoginTicket.validate_ticket(@login_ticket) login_ticket_validation_result = Castronaut::Models::LoginTicket.validate_ticket(@login_ticket)


if login_ticket_validation_result && login_ticket_validation_result.invalid? if login_ticket_validation_result && login_ticket_validation_result.invalid?
messages << login_ticket_validation_result.error_message messages << login_ticket_validation_result.message
@login_ticket = Castronaut::Models::LoginTicket.generate_from(client_host).ticket @login_ticket = Castronaut::Models::LoginTicket.generate_from(client_host).ticket
@your_mission = lambda { controller.erb :login, :locals => { :presenter => self } } # TODO: STATUS 401 @your_mission = lambda { controller.erb :login, :locals => { :presenter => self } } # TODO: STATUS 401
return self return self
Expand Down
94 changes: 94 additions & 0 deletions lib/castronaut/presenters/service_validate.rb
@@ -0,0 +1,94 @@
module Castronaut
module Presenters

class ServiceValidate
MissingCredentialsMessage = "Please supply a username and password to login."

attr_reader :controller, :your_mission
attr_accessor :messages, :login_ticket

delegate :params, :request, :to => :controller
delegate :cookies, :env, :to => :request

def initialize(controller)
@controller = controller
@messages = []
@your_mission = nil
end

def service
params['service']
end

def renewal
params['renew']
end

def service_ticket
params['ticket']
end

def proxy_callback_url
params['pgtUrl']
end

def represent!



@login_ticket = params['lt']

login_ticket_validation_result = Castronaut::Models::LoginTicket.validate_ticket(@login_ticket)

if login_ticket_validation_result && login_ticket_validation_result.invalid?
messages << login_ticket_validation_result.message
@login_ticket = Castronaut::Models::LoginTicket.generate_from(client_host).ticket
@your_mission = lambda { controller.erb :login, :locals => { :presenter => self } } # TODO: STATUS 401
return self
end

if username.blank? || password.blank?
messages << MissingCredentialsMessage
@login_ticket = Castronaut::Models::LoginTicket.generate_from(client_host).ticket
@your_mission = lambda { controller.erb :login, :locals => { :presenter => self } } # TODO: STATUS 401
return self
end

@login_ticket = Castronaut::Models::LoginTicket.generate_from(client_host).ticket

Castronaut.logger.info("#{self.class} - Logging in with username: #{username}, login ticket: #{login_ticket}, service: #{service}")

authentication_result = Castronaut::Adapters.selected_adapter.authenticate(username, password)

if authentication_result.valid?
ticket_granting_ticket = Castronaut::Models::TicketGrantingTicket.generate_for(username, client_host)
cookies[:tgt] = ticket_granting_ticket.to_cookie

if service.blank?
messages << "You have successfully logged in."
else
service_ticket = Castronaut::Models::ServiceTicket.generate_ticket_for(service, client_host, ticket_granting_ticket)

if service_ticket && service_ticket.service_uri
@your_mission = lambda { controller.redirect(service_ticket.service_uri, 303) }
return self
else
messages << "The target service your browser supplied appears to be invalid. Please contact your system administrator for help."
end
end

else
messages << authentication_result.message
end

if messages.any?
@your_mission = lambda { controller.erb :login, :locals => { :presenter => self } }
end

self
end

end

end
end
16 changes: 9 additions & 7 deletions lib/castronaut/ticket_result.rb
@@ -1,25 +1,27 @@
module Castronaut module Castronaut


class TicketResult class TicketResult

InvalidMessageCategories = %w{warn error fatal invalid}
attr_reader :ticket, :error_message
attr_reader :ticket, :message, :message_category


def initialize(ticket, error_message=nil) def initialize(ticket, message=nil, message_category=nil)
@ticket = ticket @ticket = ticket
@error_message = error_message @message = message
Castronaut.logger.info("#{self.class} - #{@error_message} for #{@ticket}") if @error_message && @ticket @message_category = message_category
Castronaut.logger.info("#{self.class} - #{@message_category} #{@message} for #{@ticket}") if @message && @ticket
end end


def username def username
ticket.username if ticket && ticket.respond_to?(:username) ticket.username if ticket && ticket.respond_to?(:username)
end end


def valid? def valid?
error_message.nil? !invalid?
end end


def invalid? def invalid?
!valid? InvalidMessageCategories.any?{ |cat| message_category.to_s.downcase.include?(cat) }
end end


end end
Expand Down

0 comments on commit f41176f

Please sign in to comment.