lib/els_token.rb in els_token-1.0.1 vs lib/els_token.rb in els_token-1.2.0
- old
+ new
@@ -1,7 +1,7 @@
require 'els_token/module_inheritable_attributes'
-require 'els_token/els_user'
+require 'els_token/els_identity'
require 'net/http'
require 'uri'
module ElsToken
@@ -12,144 +12,240 @@
base.instance_variable_set("@els_options", {})
end
module ClassMethods
- # els_config expects a nice hash telling
- # it if it will have a fake user (handy for dev)
- # and the url of the openAM REST API.
- # { faker => { user => 'username',
- # :environments => ['dev','test'] },
- # uri => 'https://openam.url' }
+ # els_config expects a hash with environmental
+ # parameters including the els gateway and expected
+ # cookie name (when used in a Rack environment)
+ # An optional fake identity can be supplied which
+ # will override any active authentication. This can
+ # be especially useful during automated testing.
+ # The fake ID can take any of the ElsIdentity properties
#
- # class MyController
- # include ElsToken
- # els_config options_hash
- # end
+ # A typical setup would initialize a options hash to
+ # include the following
+ #
+ # faker:
+ # name: neilcuk
+ # employee_number: 09095
+ # roles:
+ # - App Admins
+ # - Domain Users
+ # uri: https://els-admin.corp.aol.com:443/opensso/identity
+ # cookie: iPlanetDirectoryPro
+ # cert: /path/to/certs
+ #
+ # Do not include the faker object in your production
+ # configuration :)
+ #
+ # only the uri option is required if you are not worried
+ # about cookies and do not plan on using them. If you want
+ # to include a certificate for interacting with the ELS
+ # server then you can specify a file or directory to find
+ # the cert. By default Certificate validiation is off!
+ #
def els_config(options = {})
- @els_options = options
+ unless options["uri"]
+ raise "I need a uri to authenticate against" unless options["faker"]
+ end
+ els_options.merge!(options)
end
-
- end
+
+ def els_uri(uri = nil)
+ return els_options["uri"] unless uri
+ els_options["uri"] = uri
+ end
+
+ def els_cookie_name(cookie_name = nil)
+ return els_options["cookie"] unless cookie_name
+ els_options["cookie_name"] = uri
+ end
+
+ def els_faker(faker = {})
+ els_options["faker"] = faker
+ end
+
+ def els_options
+ @els_options
+ end
+
+ # authenticates against ELS and returns the user token
+ def authenticate(username,password,options={})
- # authenticates against ELS and returns the user token
- def authenticate(username,password)
+ begin
+ response = els_http_request("/authenticate",
+ "uri=realm=aolcorporate&username=#{username}&password=#{password}",
+ options)
+ if response.code.eql? "200"
+ # return the token
+ response.body.chomp.sub(/token\.id=/,"")
+ else
+ raise response.error!
+ end
+ rescue Net::HTTPExceptions => e1
+ raise e1, "token retrieval failed for #{username}"
+ rescue Exception => e
+ # Do not expect these. Wrapping the exception so
+ # as to not reveal the passed in password
+ puts e.backtrace
+ raise e, "unable to fetch token for #{username}"
+ end
+ end
- begin
- response = els_http_request("/authenticate","uri=realm=aolcorporate&username=#{username}&password=#{password}")
+ # passes a token to els to see if it is still valid
+ def is_token_valid?(token, options={})
+ response = els_http_request("/isTokenValid","tokenid=#{token}",options)
if response.code.eql? "200"
- # return the token
- response.body.chomp.sub(/token\.id=/,"")
+ true
else
- raise response.error!
+ false
end
- rescue Net::HTTPExceptions => e1
- raise e1, "token retrieval failed for #{username}"
- rescue Exception => e
- # Do not expect these. Wrapping the exception so
- # as to not reveal the passed in password
- raise e, "unable to fetch token for #{username}"
end
- end
-
- def is_token_valid?(token)
- response = els_http_request("/isTokenValid","tokenid=#{token}")
- if response.code.eql? "200"
- true
- else
- false
+
+
+ # obtain a friendly ElsIdentity object by passing
+ # in a token
+ def get_token_identity(token,options={})
+ ElsIdentity.new(get_raw_token_identity(token,options))
end
- end
- #extract the token from the rack cookie
- def is_cookie_token_valid?
- return true if fake_it?
- token = cookies[self.class.els_options['cookie']]
- if token.nil? || !is_token_valid?(token)
- false
- else
- true
+ # get_token_identity wraps the ELS identity response
+ # in a nice, friendly, object. If you don't like that object
+ # or need the raw data, then use this.
+ def get_raw_token_identity(token,options={})
+ response = els_http_request("/attributes","subjectid=#{token}",options)
+ if response.code.eql? "200"
+ response.body
+ else
+ response.error!
+ end
end
+
+ # When used inside a rack environment
+ # will attempt to retrieve the user token
+ # from the session cookie and return a full
+ # identity. This is pretty much a convenience
+ # method that chains is_cookie_token_valid?
+ # then get_token_identity
+ def get_identity(token, options ={})
+ return fake_id if fake_it?
+ begin
+ if is_token_valid?(token, options)
+ get_token_identity(token, options)
+ else
+ raise "token is invalid"
+ end
+ rescue Exception => e
+ raise e
+ end
+ end
+
+ private
+
+ def els_http_request(url_base_extension, query_string, options)
+ options = els_options.dup.merge(options)
+ uri = URI.parse(options['uri'] + url_base_extension)
+ uri.query=query_string
+ http = Net::HTTP.new(uri.host,uri.port)
+ http.use_ssl = true
+
+ # Use a known certificate if supplied
+ if rootca = options[:cert]
+ if File.exist? rootca
+ http.ca_file = rootca
+ elsif Dir.exist? rootca
+ http.ca.path = rootca
+ else
+ raise "${rootca} cannot be found"
+ end
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ http.verify_depth = 5
+ else
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ end
+
+ request = Net::HTTP::Get.new(uri.request_uri)
+
+ http.request(request)
+ end
+
+ def fake_it?
+ els_options.has_key? 'faker'
+ end
+
+ def fake_id
+ unless @fake_id
+ id = ElsIdentity.new
+ id.instance_variable_set("@roles",els_options['faker']['roles'])
+ id.instance_variable_set("@mail",els_options['faker']['mail'])
+ id.instance_variable_set("@last_name",els_options['faker']['last_name'])
+ id.instance_variable_set("@first_name",els_options['faker']['first_name'])
+ id.instance_variable_set("@uac",els_options['faker']['uac'])
+ id.instance_variable_set("@dn",els_options['faker']['dn'])
+ id.instance_variable_set("@common_name",els_options['faker']['common_name'])
+ id.instance_variable_set("@employee_number",els_options['faker']['employee_number'])
+ id.instance_variable_set("@display_name",els_options['faker']['display_name'])
+ id.instance_variable_set("@token_id",els_options['faker']['token_id'])
+ id.instance_variable_set("@user_status",els_options['faker']['user_status'])
+ @fake_id = id
+ end
+ @fake_id
+ end
end
- # obtain a full ElsIdentity object
+ # Instance methods
+
+ class Runner
+ include ElsToken
+ end
+
+ def authenticate(username,password)
+ Runner.authenticate(username,password,self.class.els_options)
+ end
+
+ def is_token_valid?(token)
+ Runner.is_token_valid?(token,self.class.els_options)
+ end
+
def get_token_identity(token)
- response = els_http_request("/attributes","subjectid=#{token}")
- if response.code.eql? "200"
- ElsIdentity.new(response.body)
- else
- response.error!
- end
+ Runner.get_token_identity(token,self.class.els_options)
end
- # When used inside a rack environment
- # will attempt to retrieve the user token
- # from the session cookie and return a full
- # identity
+ def get_raw_token_identity(token)
+ Runner.get_raw_token_identity(token,self.class.els_options)
+ end
+
def get_identity
- return fake_id if fake_it?
- begin
- if is_cookie_token_valid?
- get_token_identity cookies[self.class.els_options['cookie']]
- else
- raise "token is invalid"
- end
- rescue Exception => e
- raise e
- end
- end
-
- def method_missing(m, *args, &block)
- puts "Drop the crack pipe - There is no method called #{m}"
+ token = cookies[self.class.els_options['cookie']]
+ Runner.get_identity(token,self.class.els_options)
end
-
- private
- def els_http_request(url_base_extension, query_string)
- uri = URI.parse(self.class.els_options['uri'] + url_base_extension)
- uri.query=query_string
- http = Net::HTTP.new(uri.host,uri.port)
- http.use_ssl = true
-
- # Use a known certificate if supplied
- if rootca = self.class.els_options[:cert]
- if File.exist? rootca
- http.ca_file = rootca
- elsif Dir.exist? rootca
- http.ca.path = rootca
- else
- raise "${rootca} cannot be found"
- end
- http.verify_mode = OpenSSL::SSL::VERIFY_PEER
- http.verify_depth = 5
+ # extract the token from a cookie
+ # This method expects a hash called cookies
+ # to be present. It will look for a cookie with
+ # the key of the cookie value in the config hash
+ def is_cookie_token_valid?
+ return true if self.class.els_options.has_key? 'faker'
+ raise "No cookies instance found" if cookies.nil?
+ token = cookies[self.class.els_options['cookie']]
+ if token.nil? || !Runner.is_token_valid?(token,self.class.els_options)
+ false
else
- http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ true
end
-
- request = Net::HTTP::Get.new(uri.request_uri)
-
- http.request(request)
end
- def fake_it?
- self.class.els_options.has_key? 'faker'
+ # How about a few class methods of our own?
+
+ def self.authenticate(username,password,options)
+ Runner.authenticate(username,password,options)
end
-
- def fake_id
- unless @fake_id
- id = ElsIdentity.new
- id.instance_variable_set("@roles",self.class.els_options['faker']['roles'])
- id.instance_variable_set("@mail",self.class.els_options['faker']['mail'])
- id.instance_variable_set("@last_name",self.class.els_options['faker']['last_name'])
- id.instance_variable_set("@first_name",self.class.els_options['faker']['first_name'])
- id.instance_variable_set("@uac",self.class.els_options['faker']['uac'])
- id.instance_variable_set("@dn",self.class.els_options['faker']['dn'])
- id.instance_variable_set("@common_name",self.class.els_options['faker']['common_name'])
- id.instance_variable_set("@employee_number",self.class.els_options['faker']['employee_number'])
- id.instance_variable_set("@display_name",self.class.els_options['faker']['display_name'])
- id.instance_variable_set("@token_id",self.class.els_options['faker']['token_id'])
- @fake_id = id
- end
- @fake_id
+
+ def self.is_token_valid?(token, options)
+ Runner.is_token_valid?(token,options)
end
-
+
+ def self.get_identity(token, options)
+ Runner.get_identity(token,options)
+ end
end