cas-client 0.1.2.pre.p19 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6310d39c782652573f0e55f5d138f52bccd32a15f088a233bb85c9757a6d5cf4
4
- data.tar.gz: 3715448946ebae64d744d83c01a53a944adcc2a4b9dd9723b44a3d83495c4d53
3
+ metadata.gz: 3dec8e7b15d53fc005cf9b9d4d3f5bf39e1e0cf7c5df64387dd2e2615bb89bcc
4
+ data.tar.gz: 305516439c3dadc49a90cd02c27a8d65868ea8ae1b020e23c7306e10cbf165c8
5
5
  SHA512:
6
- metadata.gz: d6c941dd9c4b2c49f5f04e07a03ce13937d6445d296ec41fd85aaa163b95c65ad00b6a59b70b916bb7b7362014160823b3ff0a6878a34bd40e332168e083eefc
7
- data.tar.gz: 5e813ec40e95b7eed0606b9e485315e849acd65508ed447ef69363a1bb4ac00c69507a0d7a77440a6bb7aeeef313c73150ad1622ee80f4eacbf646b358bdee32
6
+ metadata.gz: 46b9c8224cc102f852bb2f7aded2810b4701ed662b6477812095612acd28921c3d25d2a28e452af210702b6d80e035674f4fabbc5f626572f4bd522d8ea9c9ce
7
+ data.tar.gz: ad0f99174aa6ceeea27ee2b60f756539cef7db143f5f3cd133b72d602ae9090645c7fc9ae3ebc28352466f3d8ce64b9067fd5c5cb4bb692ac98869cee46e3c9c
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cas-client (0.1.3)
5
+ rack (>= 1.3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ diff-lcs (1.3)
11
+ rack (2.0.5)
12
+ rake (10.5.0)
13
+ rspec (3.8.0)
14
+ rspec-core (~> 3.8.0)
15
+ rspec-expectations (~> 3.8.0)
16
+ rspec-mocks (~> 3.8.0)
17
+ rspec-core (3.8.0)
18
+ rspec-support (~> 3.8.0)
19
+ rspec-expectations (3.8.1)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.8.0)
22
+ rspec-mocks (3.8.0)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.8.0)
25
+ rspec-support (3.8.0)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ bundler (~> 1.16)
32
+ cas-client!
33
+ rake (~> 10.0)
34
+ rspec (~> 3.0)
35
+
36
+ BUNDLED WITH
37
+ 1.16.4
data/README.md CHANGED
@@ -22,7 +22,14 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ Configure middleware from the specific environment file
26
+
27
+ ```ruby
28
+ config.middleware.insert_after ActionDispatch::Session::CookieStore, Cas::Client::Middleware, {
29
+ server_url: "https://idpqa.americanfinancing.net",
30
+ extra_attributes: [:first_name, :last_name, :email, :external_id]
31
+ }
32
+ ```
26
33
 
27
34
  ## Development
28
35
 
@@ -32,6 +32,7 @@ Gem::Specification.new do |spec|
32
32
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
33
33
  spec.require_paths = ["lib"]
34
34
 
35
+ spec.add_dependency 'rack', '>= 1.3'
35
36
  spec.add_development_dependency "bundler", "~> 1.16"
36
37
  spec.add_development_dependency "rake", "~> 10.0"
37
38
  spec.add_development_dependency "rspec", "~> 3.0"
@@ -1,5 +1,9 @@
1
+ require 'rack'
2
+ require 'cas/client/middleware'
3
+ require 'cas/client/response'
4
+ require 'cas/client/server'
5
+ require 'cas/client/url'
1
6
  require 'cas/client/version'
2
- require 'cas/client/rack'
3
7
 
4
8
  module Cas
5
9
  module Client
@@ -0,0 +1,65 @@
1
+ require 'net/http'
2
+
3
+ module Cas
4
+ module Client
5
+ class Middleware
6
+ def initialize(app, config={})
7
+ @app = app
8
+ @config = config
9
+ @config[:extra_attributes] = [] if config[:extra_attributes].nil?
10
+ @request = nil
11
+ end
12
+
13
+ def call(env)
14
+ @request = Rack::Request.new(env)
15
+ server = Cas::Client::Server.new(@config[:server_url])
16
+ status, headers, rack_body = @app.call(env)
17
+ log(env, "Middleware called. Status: #{status}, Headers: #{headers}")
18
+
19
+ if ticket_validation?
20
+ attributes = server.validate_service(self_url(@request), ticket_param, {extra_attributes: @config[:extra_attributes]})
21
+ set_session(@request, attributes)
22
+ return redirect_to(self_url(@request))
23
+ elsif status == 401
24
+ return redirect_to(server.login_url({service_url: self_url(@request)}))
25
+ else
26
+ return [status, headers, rack_body]
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def set_session(req, attributes)
33
+ req.session['cas'] = attributes
34
+ end
35
+
36
+ def redirect_to(url, status=302)
37
+ [ status, { 'Location' => url, 'Content-Type' => 'text/plain' }, ["Redirecting you to #{url}"] ]
38
+ end
39
+
40
+ def self_url(req)
41
+ req.url.split('?')[0]
42
+ end
43
+
44
+ def ticket_validation?
45
+ !!(@request.get? && ticket_param && ticket_param.to_s =~ /\AST\-[^\s]{1,253}\Z/)
46
+ end
47
+
48
+ def ticket_param
49
+ @request.params['ticket']
50
+ end
51
+
52
+ def xml_namespace
53
+ @config[:cas_namespace] || 'cas'
54
+ end
55
+
56
+ def log(env, message, level = :info)
57
+ if env['rack.logger']
58
+ env['rack.logger'].send(level, message)
59
+ else
60
+ env['rack.errors'].write(message)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,48 @@
1
+ module Cas
2
+ module Client
3
+ class Response
4
+ def initialize(uri)
5
+ @request_uri = uri
6
+ @response = nil
7
+ end
8
+
9
+ def validate_service_response
10
+ @response = Net::HTTP.get(@request_uri)
11
+ end
12
+
13
+ def success?
14
+ @response.to_s.match(/<cas:authenticationSuccess>/).captures.length > 0
15
+ end
16
+
17
+ def all_attributes(extra_attributes)
18
+ {}.merge!(get_user(@response)).merge!(get_extra_attributes(@response, extra_attributes))
19
+ end
20
+
21
+ protected
22
+
23
+ def xml_namespace
24
+ "cas"
25
+ end
26
+
27
+ def get_user(res)
28
+ match = res.match(/<#{xml_namespace}:user>(.*)<\/#{xml_namespace}:user>/)
29
+ if match
30
+ { user: match.captures.first }
31
+ else # Failed login
32
+ {}
33
+ end
34
+ end
35
+
36
+ def get_extra_attributes(res, extra_attributes)
37
+ attributes = {}
38
+ extra_attributes.each do |ea|
39
+ match = res.match(/<#{xml_namespace}:#{ea}>(.*)<\/#{xml_namespace}:#{ea}>/)
40
+ if match
41
+ attributes[ea] = match.captures.first
42
+ end
43
+ end
44
+ attributes
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,40 @@
1
+ module Cas
2
+ module Client
3
+ class Server
4
+ def initialize(server_url)
5
+ @url = Cas::Client::URL.new(server_url)
6
+ end
7
+
8
+ def login_url(options={})
9
+ if options.key?(:service_url)
10
+ @url.append_path('/login').add_query("service=#{options[:service_url]}")
11
+ else
12
+ @url.append_path('/login')
13
+ end
14
+ end
15
+
16
+ def logout_url(options={})
17
+ if options.key?(:service_url)
18
+ @url.append_path('/logout').add_query("service=#{options[:service_url]}")
19
+ else
20
+ @url.append_path('/logout')
21
+ end
22
+ end
23
+
24
+ def validate_service(service_url, ticket, option={})
25
+ uri = Cas::Client::URL.new(validate_service_url(service_url, ticket)).to_uri
26
+ res = Cas::Client::Response.new(uri)
27
+ res.validate_service_response
28
+ res.all_attributes(option[:extra_attributes]||[])
29
+ end
30
+
31
+ protected
32
+
33
+ def validate_service_url(service_url, ticket)
34
+ protocol_path = "p3"
35
+ server_url = @url
36
+ URI("#{server_url}/#{protocol_path}/serviceValidate?service=#{service_url}&ticket=#{ticket}")
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,34 @@
1
+ module Cas
2
+ module Client
3
+ class URL
4
+ def initialize(url)
5
+ begin
6
+ @url = URI(url)
7
+ rescue URI::Error => e
8
+ raise e
9
+ end
10
+ end
11
+
12
+ def append_path(path_string)
13
+ Cas::Client::URL.new("#{@url}#{path_string}")
14
+ end
15
+
16
+ def add_query(query_string)
17
+ if @url.query.nil?
18
+ @url.query = query_string
19
+ else
20
+ @url.query += "&#{query_string}"
21
+ end
22
+ @url
23
+ end
24
+
25
+ def to_uri
26
+ URI(@url.to_s)
27
+ end
28
+
29
+ def to_s
30
+ @url.to_s
31
+ end
32
+ end
33
+ end
34
+ end
@@ -1,5 +1,5 @@
1
1
  module Cas
2
2
  module Client
3
- VERSION = "0.1.2-p19"
3
+ VERSION = "0.1.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cas-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.pre.p19
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Donavan White
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-28 00:00:00.000000000 Z
11
+ date: 2018-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -64,6 +78,7 @@ files:
64
78
  - ".travis.yml"
65
79
  - CODE_OF_CONDUCT.md
66
80
  - Gemfile
81
+ - Gemfile.lock
67
82
  - LICENSE.txt
68
83
  - README.md
69
84
  - Rakefile
@@ -71,7 +86,10 @@ files:
71
86
  - bin/setup
72
87
  - cas-client.gemspec
73
88
  - lib/cas-client.rb
74
- - lib/cas/client/rack.rb
89
+ - lib/cas/client/middleware.rb
90
+ - lib/cas/client/response.rb
91
+ - lib/cas/client/server.rb
92
+ - lib/cas/client/url.rb
75
93
  - lib/cas/client/version.rb
76
94
  homepage: ''
77
95
  licenses:
@@ -88,9 +106,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
88
106
  version: '0'
89
107
  required_rubygems_version: !ruby/object:Gem::Requirement
90
108
  requirements:
91
- - - ">"
109
+ - - ">="
92
110
  - !ruby/object:Gem::Version
93
- version: 1.3.1
111
+ version: '0'
94
112
  requirements: []
95
113
  rubyforge_project:
96
114
  rubygems_version: 2.7.6
@@ -1,22 +0,0 @@
1
- module Cas
2
- module Client
3
- class Rack
4
- def initialize(app)
5
- @app = app
6
- end
7
-
8
- def call(env)
9
- status, headers, rack_body = @app.call(env)
10
- puts "Middleware called. Status: #{status}, Headers: #{headers}"
11
-
12
- if status == 401
13
- response = "CAS Client Called!!!"
14
- headers["Content-Length"] = response.length.to_s
15
- return [status, headers, [response]]
16
- else
17
- return [status, headers, rack_body]
18
- end
19
- end
20
- end
21
- end
22
- end