Skip to content
Browse files

Initial import.

git-svn-id: https://rubycas-client.googlecode.com/svn/branches/2.x@105 e5935e18-7a1f-0410-a9c8-d10ac5b774bc
  • Loading branch information...
1 parent 348c466 commit f781966672bc4920f6fd35bf96a762d0ae83b5eb matt.zukowski committed
View
5 .loadpath
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<loadpath>
+ <pathentry path="" type="src"/>
+ <pathentry path="org.rubypeople.rdt.launching.RUBY_CONTAINER" type="con"/>
+</loadpath>
View
17 .project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>rubycas-client2</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.rubypeople.rdt.core.rubybuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.rubypeople.rdt.core.rubynature</nature>
+ </natures>
+</projectDescription>
View
0 CHANGELOG.txt
No changes.
View
0 History.txt
No changes.
View
9 Manifest.txt
@@ -0,0 +1,9 @@
+Rakefile
+README.txt
+CHANGELOG.txt
+Manifest.txt
+setup.rb
+lib/rubycas-client/version.rb
+lib/rubycas-client.rb
+test/test_helper.rb
+test/rubycas-client_test.rb
View
3 README.txt
@@ -0,0 +1,3 @@
+README for rubycas-client
+=========================
+
View
56 Rakefile
@@ -0,0 +1,56 @@
+require 'rubygems'
+require 'rake'
+require 'rake/clean'
+require 'rake/testtask'
+require 'rake/packagetask'
+require 'rake/gempackagetask'
+require 'rake/rdoctask'
+require 'rake/contrib/rubyforgepublisher'
+require 'fileutils'
+require 'hoe'
+include FileUtils
+require File.join(File.dirname(__FILE__), 'lib', 'rubycas-client', 'version')
+
+AUTHOR = ["Matt Zukowski", "Matt Walker"] # can also be an array of Authors
+EMAIL = "matt at roughest dot net"
+DESCRIPTION = "Client library for the Central Authentication Service (CAS) protocol."
+GEM_NAME = "rubycas-client" # what ppl will type to install your gem
+RUBYFORGE_PROJECT = "rubycas-client" # The unix name for your project
+HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
+
+
+NAME = "rubycas-client"
+#REV = nil
+REV = `svn info`[/Revision: (\d+)/, 1] rescue nil
+VERS = ENV['VERSION'] || (CASClient::VERSION::STRING + (REV ? ".#{REV}" : ""))
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
+RDOC_OPTS = ['--quiet', '--title', "rubycas-client documentation",
+ "--opname", "index.html",
+ "--line-numbers",
+ "--main", "README",
+ "--inline-source"]
+
+class Hoe
+ def extra_deps
+ @extra_deps.reject { |x| Array(x).first == 'hoe' }
+ end
+end
+
+# Generate all the Rake tasks
+# Run 'rake -T' to see list of generated tasks (from gem root directory)
+hoe = Hoe.new(GEM_NAME, VERS) do |p|
+ p.author = AUTHOR
+ p.description = DESCRIPTION
+ p.email = EMAIL
+ p.summary = DESCRIPTION
+ p.url = HOMEPATH
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
+ p.test_globs = ["test/**/*_test.rb"]
+ p.clean_globs = CLEAN #An array of file patterns to delete on clean.
+
+ # == Optional
+ #p.changes - A description of the release's latest changes.
+ #p.extra_deps - An array of rubygem dependencies.
+ #p.spec_extras - A hash of extra values to set in the gemspec.
+ p.extra_deps = ['activesupport']
+end
View
166 lib/casclient.rb
@@ -0,0 +1,166 @@
+require 'uri'
+require 'cgi'
+require 'net/https'
+require 'rexml/document'
+
+require 'active_support'
+
+module CASClient
+ # The client brokers all HTTP transactions with the CAS server.
+ class Client
+ attr_reader :login_url, :validate_url, :protocol
+
+ def configure(conf)
+ raise ArgumentError, "Missing :login_url parameter!" unless conf[:login_url]
+ raise ArgumentError, "Missing :validate_url parameter!" unless conf[:validate_url]
+
+ @login_url = conf[:login_url]
+ @validate_url = conf[:validate_url]
+
+ @session_username = conf[:session_username_key] || :casfilteruser
+ end
+
+ def validate_service_ticket(st)
+ uri = URI.parse(@validate_url)
+ h = query_to_hash(uri.query)
+ h['service'] = st.service
+ h['ticket'] = st.ticket
+ h['renew'] = 1 if st.renew
+ uri.query = hash_to_query(h)
+
+ st.response = fetch_cas_response(uri)
+
+ return st
+ end
+ alias validate_proxy_ticket validate_service_ticket
+
+ private
+ # Fetches a CAS Response from the given URI.
+ def fetch_cas_response(uri)
+ uri = URI.parse(uri) unless uri.kind_of? URI
+ https = Net::HTTP.new(uri.host, uri.port)
+ https.use_ssl = (uri.scheme == 'https')
+ raw_res = https.start do |conn|
+ conn.get("#{uri.path}?#{uri.query}").body.strip
+ end
+
+ #TODO: check to make sure that response code is 200 and handle errors otherwise
+
+ Response.new(raw_res.body)
+ end
+ end
+
+ # Represents a CAS service ticket.
+ class ServiceTicket
+ attr_reader :ticket, :service, :renew
+ attr_accessor :response
+
+ def initialize(ticket, service, renew = false)
+ @ticket = ticket
+ @service = service
+ @renew = renew
+ end
+
+ def is_valid?
+ response.is_success?
+ end
+
+ def has_been_validated?
+ not response.nil?
+ end
+ end
+
+ # Represents a CAS proxy ticket.
+ class ProxyTicket < ServiceTicket
+ attr_reader :pgt_url
+
+ def initialize(ticket, service, pgt_url, renew = false)
+ @ticket = ticket
+ @service = service
+ @pgt_url = pgt_url
+ @renew = renew
+ end
+ end
+
+ # Represents a response from a CAS server.
+ class Response
+ attr_reader :xml, :parsetime
+ attr_reader :protocol, :user, :pgt, :proxies, :extra_attributes
+
+ def initialize(raw_text)
+ parse(raw_text)
+ end
+
+ def parse(raw_text)
+ @parsetime = Time.now
+ begin
+ doc = REXML::Document.new(raw_text)
+ rescue REXML::ParseException => e
+ if raw_text =~ /^(yes|no)\n(.*?)\n$/m
+ @protocol = 1.0
+ @valid = $~[1] == 'yes'
+ @user = $~[2]
+ return
+ end
+ raise BadResponseException, "MALFORMED CAS RESPONSE:\n#{str.inspect}\n\nEXCEPTION:\n#{e}"
+ end
+
+ unless doc.elements && doc.elements["cas:serviceResponse"]
+ raise BadResponseException, "BAD CAS RESPONSE:\n#{str.inspect}\n\nXML DOC:\n#{doc.inspect}"
+ end
+
+ # if we got this far then we've got a valid XML response, so we're doing CAS 2.0
+ @protocol = 2.0
+
+ @xml = CASResponse.new(doc.elements["cas:serviceResponse"].elements[1])
+
+ if is_success?
+ @user = @xml.elements["cas:user"].text.strip if @xml.elements["cas:user"]
+ @pgt = @xml.elements["cas:proxyGrantingTicket"] if @xml.elements["cas:proxyGrantingTicket"]
+
+ @xml.elements.to_a('//cas:authenticationSuccess/cas:proxies/cas:proxy').each do |el|
+ @other_attributes.merge!(Hash.from_xml(el.to_s)) unless el.prefix == 'cas'
+ end
+
+ @extra_attributes = {}
+ @xml.elements.to_a('//cas:authenticationSuccess/*').each do |el|
+ @extra_attributes.merge!(Hash.from_xml(el.to_s)) unless el.prefix == 'cas'
+ end
+ elsif is_failure?
+
+ else
+ # this should never happen!
+ raise BadResponseException, "BAD CAS RESPONSE:\n#{str.inspect}\n\nXML DOC:\n#{doc.inspect}"
+ end
+
+ end
+
+ def is_success?
+ @valid == true || @xml.name == "authenticationSuccess"
+ end
+
+ def is_failure?
+ @valid == false || @xml.name = "authenticationFailure"
+ end
+
+ private
+ def query_to_hash(query)
+ CGI.parse(query)
+ end
+
+ def hash_to_query(hash)
+ pairs = []
+ hash.each do |k, vals|
+ vals = [vals] unless vals.kind_of Array
+ v.each {|v| paris << "#{CGI.escape(k)}=#{CGI.escape(v)}"}
+ end
+ pairs.join("&")
+ end
+ end
+
+ class CASException < Exception
+ end
+
+ class BadResponseException < CASException
+ end
+end
View
0 lib/casclient/client.rb
No changes.
View
0 lib/casclient/models.rb
No changes.
View
9 lib/casclient/version.rb
@@ -0,0 +1,9 @@
+module CASClient #:nodoc:
+ module VERSION #:nodoc:
+ MAJOR = 1
+ MINOR = 9
+ TINY = 9
+
+ STRING = [MAJOR, MINOR, TINY].join('.')
+ end
+end
View
1 lib/rubycas-client.rb
@@ -0,0 +1 @@
+require 'lib/casserver'
View
1,585 setup.rb
1,585 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
33 test/casclient_test.rb
@@ -0,0 +1,33 @@
+require File.dirname(__FILE__) + '/test_helper.rb'
+
+class CASClientTest < Test::Unit::TestCase
+
+ def setup
+ @cas_success = %{
+ <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
+ <cas:authenticationSuccess>
+ <cas:user>mzukowski</cas:user>
+ <cas:proxyGrantingTicket>PGTIOU-84678-8a9d</cas:proxyGrantingTicket>
+ <cas:proxies>
+ <cas:proxy>https://proxy2/pgtUrl</cas:proxy>
+ <cas:proxy>https://proxy1/pgtUrl</cas:proxy>
+ </cas:proxies>
+ <test:email>mzukowski@example.foo</test:email>
+ <misc>Matt Zukowski</misc>
+ </cas:authenticationSuccess>
+ </cas:serviceResponse>
+ }
+
+ @cas_failure = %{
+ <cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
+ <cas:authenticationFailure code="INVALID_TICKET">
+ Ticket ST-1856339-aA5Yuvrxzpv8Tau1cYQ7 not recognized
+ </cas:authenticationFailure>
+ </cas:serviceResponse>
+ }
+ end
+
+ def test_truth
+ assert true
+ end
+end
View
2 test/test_helper.rb
@@ -0,0 +1,2 @@
+require 'test/unit'
+require File.dirname(__FILE__) + '/../lib/rubycas-client'

0 comments on commit f781966

Please sign in to comment.
Something went wrong with that request. Please try again.