casual 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Zach Holman
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.markdown ADDED
@@ -0,0 +1,39 @@
1
+ # Casual
2
+ ### Casual is a tiny [CAS](http://en.wikipedia.org/wiki/Central_Authentication_Service) client
3
+
4
+ There's a [few](http://github.com/gunark/rubycas-client) [CAS](http://github.com/p8/casablanca) [clients](http://github.com/jamesarosen/casrack_the_authenticator) in [the Ruby world](http://github.com/search?langOverride=&language=rb&q=cas&repo=&start_value=1&type=Repositories&x=25&y=13). Go check them out; there's a very good chance they'll fit your needs. I'll wait.
5
+
6
+ Cool. What I didn't like from existing solutions was that they assumed you were using Rails, they assumed you would use CAS in a particular fashion, and CAS seemed too straightforward to muddy it up with a ten-thousand line client library.
7
+
8
+ Casual is a übertiny client that doesn't hook into a Rails `before_filter` or deep into Rack middleware. It'll work in irb, it'll work in a simple controller, it'll work underwater. It's based off of another tiny client from [Texas A&M](http://http.tamu.edu/auth/caslibraries/ruby/), except generalized for use outside the school and to avoid REXML (ew).
9
+
10
+ Casual will work for casual use, like simple and straightforward authentication requirements or as a way to programmatically play around with and understand CAS itself.
11
+
12
+ ## Codes
13
+
14
+ ### Fake end-to-end CAS authentication
15
+ This bypasses the intermediary CAS single sign-on point, which is frowned upon in the CAS docs since the client gains access to usernames + passwords. But it's also a-nice-to-have if you're building an internal app that is entirely in your control.
16
+
17
+ require 'casual'
18
+ casual = Casual::Client.new(:server_path => 'local-cas-server'
19
+ :port => 443, # defaults to 443 (SSL)
20
+ :callback_url => 'http://your.example.com')
21
+ casual.authenticate('holman','super_secret_password')
22
+ # => returns 'holman' if I'm logged in, or nil if not
23
+
24
+ ### Simulate traditional CAS authentication
25
+ This is closer to the normal CAS authentication process. It requires that you send the user off to your CAS login page to transfer tickets between your app and the CAS server, so you can't just do it all in one request.
26
+
27
+ require 'casual'
28
+ casual = Casual::Client.new(:server_path => 'local-cas-server'
29
+ :port => 443, # defaults to 443 (SSL)
30
+ :callback_url => 'http://your.example.com')
31
+ casual.authentication_url
32
+ # returns URL your user should be redirected to
33
+ # after CAS login, redirects you to +callback_url+ with ticket as param
34
+ casual.user_login(ticket)
35
+ # returns username if valid, nil if invalid
36
+
37
+ ## Casual.
38
+
39
+ by [@holman](http://twitter.com/holman).
data/Rakefile ADDED
@@ -0,0 +1,53 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "casual"
8
+ gem.summary = "A tiny CAS client for Ruby"
9
+ gem.description = "A tiny CAS client for Ruby"
10
+ gem.email = "github.com@zachholman.com"
11
+ gem.homepage = "http://github.com/holman/casual"
12
+ gem.authors = ["Zach Holman"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ gem.add_dependency 'nokogiri'
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
19
+ end
20
+
21
+ require 'rake/testtask'
22
+ Rake::TestTask.new(:test) do |test|
23
+ test.libs << 'lib' << 'test'
24
+ test.pattern = 'test/**/test_*.rb'
25
+ test.verbose = true
26
+ end
27
+
28
+ begin
29
+ require 'rcov/rcovtask'
30
+ Rcov::RcovTask.new do |test|
31
+ test.libs << 'test'
32
+ test.pattern = 'test/**/test_*.rb'
33
+ test.verbose = true
34
+ end
35
+ rescue LoadError
36
+ task :rcov do
37
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
38
+ end
39
+ end
40
+
41
+ task :test => :check_dependencies
42
+
43
+ task :default => :test
44
+
45
+ require 'rake/rdoctask'
46
+ Rake::RDocTask.new do |rdoc|
47
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
48
+
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "casual #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
data/casual.gemspec ADDED
@@ -0,0 +1,54 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{casual}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Zach Holman"]
12
+ s.date = %q{2010-03-31}
13
+ s.description = %q{A tiny CAS client for Ruby}
14
+ s.email = %q{github.com@zachholman.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.markdown"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.markdown",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "casual.gemspec",
27
+ "lib/casual.rb",
28
+ "test/helper.rb",
29
+ "test/test_casual.rb"
30
+ ]
31
+ s.homepage = %q{http://github.com/holman/casual}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.3.6}
35
+ s.summary = %q{A tiny CAS client for Ruby}
36
+ s.test_files = [
37
+ "test/helper.rb",
38
+ "test/test_casual.rb"
39
+ ]
40
+
41
+ if s.respond_to? :specification_version then
42
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
+ s.specification_version = 3
44
+
45
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
46
+ s.add_runtime_dependency(%q<nokogiri>, [">= 0"])
47
+ else
48
+ s.add_dependency(%q<nokogiri>, [">= 0"])
49
+ end
50
+ else
51
+ s.add_dependency(%q<nokogiri>, [">= 0"])
52
+ end
53
+ end
54
+
data/lib/casual.rb ADDED
@@ -0,0 +1,50 @@
1
+ require 'net/https'
2
+ require 'nokogiri'
3
+
4
+ module Casual
5
+ class Client
6
+ attr_accessor :server_path, :callback_url, :port
7
+
8
+ def initialize(config)
9
+ @server_path = config[:server_path]
10
+ @callback_url = config[:callback_url]
11
+ @port = config[:port] || 443
12
+ end
13
+
14
+ def authorization_url
15
+ "#{server_url}/login?service=#{callback_url}"
16
+ end
17
+
18
+ def authenticate(username,password)
19
+ ticket = acquire_ticket
20
+ params = "username=#{username}&password=#{password}&lt=#{ticket}"
21
+ status,response = connection.post('/login', params)#.last
22
+ (status.code == '200') ? username : nil
23
+ end
24
+
25
+ def acquire_ticket
26
+ login_page = connection.get('/login')
27
+ Nokogiri::HTML(login_page.body).css('input#lt').first['value']
28
+ end
29
+
30
+ def connection
31
+ http = Net::HTTP.new(server_path, port)
32
+ http.use_ssl = true
33
+ http
34
+ end
35
+
36
+ def authenticate_ticket(ticket)
37
+ connection.get("/serviceValidate?service=#{callback_url}&ticket=#{ticket}").body
38
+ end
39
+
40
+ def user_login(ticket)
41
+ user = Nokogiri::XML(authenticate_ticket(ticket)).xpath('//cas:authenticationSuccess //cas:user').text
42
+ user.strip != '' ? user : nil
43
+ end
44
+
45
+ def server_url
46
+ "https://#{server_path}:#{port}"
47
+ end
48
+
49
+ end
50
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'redgreen'
4
+ require 'rr'
5
+
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
8
+ require 'casual'
9
+
10
+ class Test::Unit::TestCase
11
+ include RR::Adapters::TestUnit
12
+ end
@@ -0,0 +1,42 @@
1
+ require 'helper'
2
+
3
+ class TestCasual < Test::Unit::TestCase
4
+
5
+ def setup
6
+ @client = Casual::Client.new(:server_path => 'localhost',
7
+ :port => 443,
8
+ :callback_url => 'http://localhost')
9
+ end
10
+
11
+ def test_authorization_url
12
+ assert_equal @client.authorization_url,
13
+ "https://localhost:443/login?service=http://localhost"
14
+ end
15
+
16
+ def test_user_login_success
17
+ mock(@client).authenticate_ticket.with('GOLDEN_TICKET_LOL') {
18
+ '<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">'+
19
+ '<cas:authenticationSuccess><cas:user>holman</cas:user></cas:authenticationSuccess>'+
20
+ '</cas:serviceResponse>'
21
+ }
22
+ assert_equal @client.user_login('GOLDEN_TICKET_LOL'), 'holman'
23
+ end
24
+
25
+ def test_user_login_fail
26
+ mock(@client).authenticate_ticket.with('GOLDEN_TICKET_FAIL') {
27
+ '<cas:serviceResponse xmlns:cas="http://www.yale.edu/tp/cas">'+
28
+ '<cas:authenticationFailure code="INVALID_TICKET">Ticket \'GOLDEN_TICKET_FAIL\' not recognized.'+
29
+ '</cas:authenticationFailure></cas:serviceResponse>'
30
+ }
31
+ assert_equal @client.user_login('GOLDEN_TICKET_FAIL'), nil
32
+ end
33
+
34
+ def test_authenticate_success
35
+ connection_mock = mock('').post.with_any_args {
36
+ [Net::HTTPSuccess.new('','200',''), '<div class="messagebox confirmation">You have successfully logged in.</div>']
37
+ }
38
+ mock(@client).connection { connection_mock }
39
+ mock(@client).acquire_ticket { 'a_ticket' }
40
+ assert_equal @client.authenticate('holman','lolsecret'), 'holman'
41
+ end
42
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: casual
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Zach Holman
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-03-31 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: nokogiri
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description: A tiny CAS client for Ruby
33
+ email: github.com@zachholman.com
34
+ executables: []
35
+
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - LICENSE
40
+ - README.markdown
41
+ files:
42
+ - .document
43
+ - .gitignore
44
+ - LICENSE
45
+ - README.markdown
46
+ - Rakefile
47
+ - VERSION
48
+ - casual.gemspec
49
+ - lib/casual.rb
50
+ - test/helper.rb
51
+ - test/test_casual.rb
52
+ has_rdoc: true
53
+ homepage: http://github.com/holman/casual
54
+ licenses: []
55
+
56
+ post_install_message:
57
+ rdoc_options:
58
+ - --charset=UTF-8
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ segments:
66
+ - 0
67
+ version: "0"
68
+ required_rubygems_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ requirements: []
76
+
77
+ rubyforge_project:
78
+ rubygems_version: 1.3.6
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: A tiny CAS client for Ruby
82
+ test_files:
83
+ - test/helper.rb
84
+ - test/test_casual.rb