Skip to content

Commit

Permalink
Initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
ctria committed Dec 29, 2009
0 parents commit 13897bf
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 0 deletions.
1 change: 1 addition & 0 deletions init.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'authlogic_x509'
6 changes: 6 additions & 0 deletions lib/authlogic_x509.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require "authlogic_x509/version"
require "authlogic_x509/acts_as_authentic"
require "authlogic_x509/session"

ActiveRecord::Base.send(:include, AuthlogicX509::ActsAsAuthentic)
Authlogic::Session::Base.send(:include, AuthlogicX509::Session)
18 changes: 18 additions & 0 deletions lib/authlogic_x509/acts_as_authentic.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module AuthlogicX509
module ActsAsAuthentic
def self.included(klass)
klass.class_eval do
extend Config
add_acts_as_authentic_module(Methods, :prepend)
end
end

module Config

end

module Methods

end
end
end
82 changes: 82 additions & 0 deletions lib/authlogic_x509/session.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
module AuthlogicX509
module Session
# Add a simple openid_identifier attribute and some validations for the field.
def self.included(klass)
klass.class_eval do
extend Config
include Methods
end
end

module Config
# Once X509 authentication has succeeded we need to find the user in the database. By default this just calls the
# find_by_x509_subject_dn method provided by ActiveRecord. If you have a more advanced set up and need to find users
# differently specify your own method and define your logic in there.
#
# For example, if you allow users to store multiple x509 subject DNs with their account, you might do something like:
#
# class User < ActiveRecord::Base
# def self.find_by_x509_subject_dn(login)
# first(:conditions => ["#{X509Login.table_name}.login = ?", login], :join => :x509_logins)
# end
# end
#
# * <tt>Default:</tt> :find_by_x509_subject_dn
# * <tt>Accepts:</tt> Symbol
def find_by_x509_login_method(value = nil)
rw_config(:find_by_x509_login_method, value, :find_by_x509_subject_dn)
end
alias_method :find_by_x509_login_method=, :find_by_x509_login_method

end

module Methods
def self.included(klass)
klass.class_eval do
attr_accessor :x509_login
attr_accessor :x509_subject_dn
validate :validate_by_x509, :if => :authenticating_with_x509?
end
end

# Hooks into credentials so that you can pass an :x509_login key.
def credentials=(value)
super
values = value.is_a?(Array) ? value : [value]
hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
if !hash.nil?
self.x509_login = hash[:x509_login] if hash.key?(:x509_login)
end
end

private
def authenticating_with_x509?
attempted_record.nil? && errors.empty? && x509_login
end

def validate_by_x509

if controller.local_request?
self.x509_subject_dn = "/CN=Local Request"
elsif controller.request.env['SSL_CLIENT_S_DN'] =~ /CN/
self.x509_subject_dn = controller.request.env['SSL_CLIENT_S_DN']
elsif controller.request.env['REDIRECT_SSL_CLIENT_S_DN'] =~ /CN/
self.x509_subject_dn = controller.request.env['REDIRECT_SSL_CLIENT_S_DN']
elsif controller.request.env['HTTP_REDIRECT_SSL_CLIENT_S_DN'] =~ /CN/
self.x509_subject_dn = controller.request.env['HTTP_REDIRECT_SSL_CLIENT_S_DN']
end

if self.x509_subject_dn
self.attempted_record = klass.send(find_by_x509_login_method, x509_subject_dn)
errors.add(:x509_subject_dn, I18n.t('error_messages.x509_subject_dn_not_found', :default => "does not exist")) if attempted_record.blank?
else
errors.add_to_base("Subject DN not found")
end
end

def find_by_x509_login_method
self.class.find_by_x509_login_method
end
end
end
end
51 changes: 51 additions & 0 deletions lib/authlogic_x509/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module AuthlogicX509
# A class for describing the current version of a library. The version
# consists of three parts: the +major+ number, the +minor+ number, and the
# +tiny+ (or +patch+) number.
class Version
include Comparable

# A convenience method for instantiating a new Version instance with the
# given +major+, +minor+, and +tiny+ components.
def self.[](major, minor, tiny)
new(major, minor, tiny)
end

attr_reader :major, :minor, :tiny

# Create a new Version object with the given components.
def initialize(major, minor, tiny)
@major, @minor, @tiny = major, minor, tiny
end

# Compare this version to the given +version+ object.
def <=>(version)
to_i <=> version.to_i
end

# Converts this version object to a string, where each of the three
# version components are joined by the '.' character. E.g., 2.0.0.
def to_s
@to_s ||= [@major, @minor, @tiny].join(".")
end

# Converts this version to a canonical integer that may be compared
# against other version objects.
def to_i
@to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
end

def to_a
[@major, @minor, @tiny]
end

MAJOR = 0
MINOR = 0
TINY = 1

# The current version as a Version instance
CURRENT = new(MAJOR, MINOR, TINY)
# The current version as a String
STRING = CURRENT.to_s
end
end

0 comments on commit 13897bf

Please sign in to comment.