authlogic_radius 0.0.4
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.
- data/LICENSE +20 -0
- data/README.rdoc +57 -0
- data/lib/authlogic_radius/acts_as_authentic.rb +44 -0
- data/lib/authlogic_radius/session.rb +167 -0
- data/lib/authlogic_radius/version.rb +51 -0
- data/lib/authlogic_radius.rb +6 -0
- metadata +96 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Brad Langhorst of New England Biolabs
|
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.rdoc
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
== Authlogic RADIUS
|
2
|
+
|
3
|
+
|
4
|
+
This is a simple gem to allow authentication against a radius server
|
5
|
+
|
6
|
+
Mostly it is a duplication or authlogic_ldap, with a global replace of "ldap" with "radius"...
|
7
|
+
and a few RADIUS specific bits.
|
8
|
+
|
9
|
+
|
10
|
+
== Links
|
11
|
+
* <b>radiustar</b> http://github.com/pjdavis/radiustar
|
12
|
+
* <b>authlogic</b> http://github.com/binarylogic/authlogic
|
13
|
+
* <b>authlogic_ldap</b> http://github.com/binarylogic/authlogic_ldap
|
14
|
+
|
15
|
+
|
16
|
+
== Installation
|
17
|
+
=== 1. Add fields to your database
|
18
|
+
|
19
|
+
class AddRadiusFields < ActiveRecord::Migration
|
20
|
+
def self.up
|
21
|
+
add_column :users, :radius_login, :string
|
22
|
+
add_index :users, :radius_login
|
23
|
+
|
24
|
+
change_column :users, :login, :string, :default => nil, :null => true
|
25
|
+
change_column :users, :crypted_password, :string, :default => nil, :null => true
|
26
|
+
change_column :users, :password_salt, :string, :default => nil, :null => true
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.down
|
30
|
+
remove_column :users, :radius_login
|
31
|
+
|
32
|
+
[:login, :crypted_password, :password_salt].each do |field|
|
33
|
+
User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? }
|
34
|
+
change_column :users, field, :string, :default => "", :null => false
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
=== 2. Install authlogic_radius gem
|
40
|
+
Add the gem to your environment's list of gems
|
41
|
+
config.gem "authlogic_radius"
|
42
|
+
$ sudo rake gems:install
|
43
|
+
|
44
|
+
|
45
|
+
=== 3. Update your views to use :radius_login and :radius_password
|
46
|
+
|
47
|
+
=== 4. Add/update configuration in your UserSession model with the RADIUS details
|
48
|
+
class UserSession < Authlogic::Session::Base
|
49
|
+
...
|
50
|
+
self.radius_host = "your.radius.server"
|
51
|
+
self.radius_shared_secret = 'super-secret' #not the same as the user password...
|
52
|
+
#optionally
|
53
|
+
self.radius_port = 1812
|
54
|
+
self.radius_timeout = 2
|
55
|
+
...
|
56
|
+
end
|
57
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'authlogic'
|
2
|
+
|
3
|
+
module AuthlogicRadius
|
4
|
+
module ActsAsAuthentic
|
5
|
+
def self.included(klass)
|
6
|
+
klass.class_eval do
|
7
|
+
extend Config
|
8
|
+
add_acts_as_authentic_module(Methods, :prepend)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module Config
|
13
|
+
# Whether or not to validate the radius_login field. If set to false ALL radius validation will need to be
|
14
|
+
# handled by you.
|
15
|
+
#
|
16
|
+
# * <tt>Default:</tt> true
|
17
|
+
# * <tt>Accepts:</tt> Boolean
|
18
|
+
def validate_radius_login(value = nil)
|
19
|
+
rw_config(:validate_radius_login, value, true)
|
20
|
+
end
|
21
|
+
alias_method :validate_radius_login=, :validate_radius_login
|
22
|
+
end
|
23
|
+
|
24
|
+
module Methods
|
25
|
+
def self.included(klass)
|
26
|
+
klass.class_eval do
|
27
|
+
attr_accessor :radius_password
|
28
|
+
|
29
|
+
if validate_radius_login
|
30
|
+
validates_uniqueness_of :radius_login, :scope => validations_scope, :if => :using_radius?
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def using_radius?
|
38
|
+
respond_to?(:radius_login) && respond_to?(:radius_password) &&
|
39
|
+
(!radius_login.blank? || !radius_password.blank?)
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'timeout'
|
2
|
+
require 'radiustar'
|
3
|
+
|
4
|
+
module AuthlogicRadius
|
5
|
+
module Session
|
6
|
+
|
7
|
+
def self.included(klass)
|
8
|
+
klass.class_eval do
|
9
|
+
extend Config
|
10
|
+
include Methods
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module Config
|
15
|
+
# The host of your RADIUS server.
|
16
|
+
#
|
17
|
+
# * <tt>Default:</tt> nil
|
18
|
+
# * <tt>Accepts:</tt> String
|
19
|
+
def radius_host(value = nil)
|
20
|
+
rw_config(:radius_host, value)
|
21
|
+
end
|
22
|
+
alias_method :radius_host=, :radius_host
|
23
|
+
|
24
|
+
# The port of your RADIUS server.
|
25
|
+
#
|
26
|
+
# * <tt>Default:</tt> 18121
|
27
|
+
# * <tt>Accepts:</tt> Fixnum, integer
|
28
|
+
def radius_port(value = nil)
|
29
|
+
rw_config(:radius_port, value, 1812)
|
30
|
+
end
|
31
|
+
alias_method :radius_port=, :radius_port
|
32
|
+
|
33
|
+
# The shared secret issued by your RADIUS server
|
34
|
+
#
|
35
|
+
# * <tt>Default:</tt> nil
|
36
|
+
# * <tt>Accepts:</tt> String
|
37
|
+
def radius_shared_secret(value = nil)
|
38
|
+
rw_config(:radius_shared_secret, value)
|
39
|
+
end
|
40
|
+
alias_method :radius_shared_secret=, :radius_shared_secret
|
41
|
+
|
42
|
+
|
43
|
+
# How long to wait for a response from the RADIUS server
|
44
|
+
# * <tt>Default:</tt> 2 seconds
|
45
|
+
# * <tt>Accepts:</tt> Fixnum, integer
|
46
|
+
def radius_timeout(value = 2)
|
47
|
+
rw_config(:radius_timeout, value)
|
48
|
+
end
|
49
|
+
alias_method :radius_timeout=, :radius_timeout
|
50
|
+
|
51
|
+
# Which database field should be used to store the radius login
|
52
|
+
# * <tt>Defaults:</tt> :radius_login
|
53
|
+
# * <tt>Accepts:</tt> Symbol
|
54
|
+
def radius_login_field(value=nil)
|
55
|
+
rw_config(:radius_login_field, value, :radius_login)
|
56
|
+
end
|
57
|
+
alias_method :radius_login_field=, :radius_login_field
|
58
|
+
|
59
|
+
# Once RADIUS authentication has succeeded we need to find the user in the database. By default this just calls the
|
60
|
+
# find_by_radius_login method provided by ActiveRecord. If you have a more advanced set up and need to find users
|
61
|
+
# differently specify your own method and define your logic in there.
|
62
|
+
#
|
63
|
+
# For example, if you allow users to store multiple radius logins with their account, you might do something like:
|
64
|
+
#
|
65
|
+
# class User < ActiveRecord::Base
|
66
|
+
# def self.find_by_radius_login(login)
|
67
|
+
# first(:conditions => ["#{RadiusLogin.table_name}.login = ?", login], :join => :radius_logins)
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# * <tt>Default:</tt> :find_by_radius_login
|
72
|
+
# * <tt>Accepts:</tt> Symbol
|
73
|
+
def find_by_radius_login_method(value = nil)
|
74
|
+
rw_config(:find_by_radius_login_method, value, :find_by_radius_login)
|
75
|
+
end
|
76
|
+
alias_method :find_by_radius_login_method=, :find_by_radius_login_method
|
77
|
+
end
|
78
|
+
|
79
|
+
module Methods
|
80
|
+
def self.included(klass)
|
81
|
+
klass.class_eval do
|
82
|
+
attr_accessor :radius_login
|
83
|
+
attr_accessor :radius_password
|
84
|
+
validate :validate_by_radius, :if => :authenticating_with_radius?
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Hooks into credentials to print out meaningful credentials for RADIUS authentication.
|
89
|
+
def credentials
|
90
|
+
if authenticating_with_radius?
|
91
|
+
details = {}
|
92
|
+
details[:radius_login] = send(radius_login_field)
|
93
|
+
details[:radius_host] = radius_host
|
94
|
+
details[:radius_password] = "<protected>"
|
95
|
+
details[:radius_shared_secret] = "<protected>"
|
96
|
+
details
|
97
|
+
else
|
98
|
+
super
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Hooks into credentials so that you can pass an :radius_login and :radius_password key.
|
103
|
+
def credentials=(value)
|
104
|
+
super
|
105
|
+
values = value.is_a?(Array) ? value : [value]
|
106
|
+
hash = values.first.is_a?(Hash) ? values.first.with_indifferent_access : nil
|
107
|
+
if !hash.nil?
|
108
|
+
self.radius_login = hash[:radius_login] if hash.key?(:radius_login)
|
109
|
+
self.radius_password = hash[:radius_password] if hash.key?(:radius_password)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
def authenticating_with_radius?
|
115
|
+
return radius_host && radius_shared_secret && radius_login
|
116
|
+
end
|
117
|
+
|
118
|
+
def validate_by_radius
|
119
|
+
errors.add(:radius_login, I18n.t('error_messages.radius_login_blank', :default => "can not be blank")) if radius_login.blank?
|
120
|
+
errors.add(:radius_password, I18n.t('error_messages.radius_password_blank', :default => "can not be blank")) if radius_password.blank?
|
121
|
+
return if errors.count > 0
|
122
|
+
|
123
|
+
begin
|
124
|
+
req = Radiustar::Request.new("#{radius_host}:#{radius_port}")
|
125
|
+
rescue => e
|
126
|
+
errors.add_to_base("Unable to contact RADIUS server at #{radius_host}:#{radius_port}")
|
127
|
+
return
|
128
|
+
end
|
129
|
+
|
130
|
+
begin
|
131
|
+
Timeout.timeout(radius_timeout) do
|
132
|
+
if req.authenticate(radius_login,radius_password,radius_shared_secret)
|
133
|
+
self.attempted_record = search_for_record(find_by_radius_login_method, radius_login)
|
134
|
+
errors.add(:radius_login, I18n.t('error_messages.radius_login_not_found', :default => "does not exist")) if attempted_record.blank?
|
135
|
+
else
|
136
|
+
errors.add_to_base("Authentication failed")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
rescue Timeout::Error
|
140
|
+
errors.add_to_base("No response from RADIUS server at #{radius_host}:#{radius_port}")
|
141
|
+
rescue => e
|
142
|
+
errors.add_to_base(e.to_s)
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def radius_host
|
147
|
+
self.class.radius_host
|
148
|
+
end
|
149
|
+
|
150
|
+
def radius_port
|
151
|
+
self.class.radius_port
|
152
|
+
end
|
153
|
+
|
154
|
+
def radius_shared_secret
|
155
|
+
self.class.radius_shared_secret
|
156
|
+
end
|
157
|
+
|
158
|
+
def radius_timeout
|
159
|
+
self.class.radius_timeout
|
160
|
+
end
|
161
|
+
|
162
|
+
def find_by_radius_login_method
|
163
|
+
self.class.find_by_radius_login_method
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module AuthlogicRadius
|
2
|
+
# A class for describing the current version of a library. The version
|
3
|
+
# consists of three parts: the +major+ number, the +minor+ number, and the
|
4
|
+
# +tiny+ (or +patch+) number.
|
5
|
+
class Version
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
# A convenience method for instantiating a new Version instance with the
|
9
|
+
# given +major+, +minor+, and +tiny+ components.
|
10
|
+
def self.[](major, minor, tiny)
|
11
|
+
new(major, minor, tiny)
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :major, :minor, :tiny
|
15
|
+
|
16
|
+
# Create a new Version object with the given components.
|
17
|
+
def initialize(major, minor, tiny)
|
18
|
+
@major, @minor, @tiny = major, minor, tiny
|
19
|
+
end
|
20
|
+
|
21
|
+
# Compare this version to the given +version+ object.
|
22
|
+
def <=>(version)
|
23
|
+
to_i <=> version.to_i
|
24
|
+
end
|
25
|
+
|
26
|
+
# Converts this version object to a string, where each of the three
|
27
|
+
# version components are joined by the '.' character. E.g., 2.0.0.
|
28
|
+
def to_s
|
29
|
+
@to_s ||= [@major, @minor, @tiny].join(".")
|
30
|
+
end
|
31
|
+
|
32
|
+
# Converts this version to a canonical integer that may be compared
|
33
|
+
# against other version objects.
|
34
|
+
def to_i
|
35
|
+
@to_i ||= @major * 1_000_000 + @minor * 1_000 + @tiny
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_a
|
39
|
+
[@major, @minor, @tiny]
|
40
|
+
end
|
41
|
+
|
42
|
+
MAJOR = 0
|
43
|
+
MINOR = 0
|
44
|
+
TINY = 1
|
45
|
+
|
46
|
+
# The current version as a Version instance
|
47
|
+
CURRENT = new(MAJOR, MINOR, TINY)
|
48
|
+
# The current version as a String
|
49
|
+
STRING = CURRENT.to_s
|
50
|
+
end
|
51
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: authlogic_radius
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 4
|
9
|
+
version: 0.0.4
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Brad Langhorst
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-01 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: authlogic
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 2
|
29
|
+
- 0
|
30
|
+
version: "2.0"
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: *id001
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: radiustar
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
segments:
|
41
|
+
- 0
|
42
|
+
- 0
|
43
|
+
- 3
|
44
|
+
version: 0.0.3
|
45
|
+
type: :runtime
|
46
|
+
version_requirements: *id002
|
47
|
+
description: |
|
48
|
+
This is a simple gem to allow authentication against a RADIUS server.
|
49
|
+
|
50
|
+
email: langhorst@neb.com
|
51
|
+
executables: []
|
52
|
+
|
53
|
+
extensions: []
|
54
|
+
|
55
|
+
extra_rdoc_files:
|
56
|
+
- LICENSE
|
57
|
+
- README.rdoc
|
58
|
+
files:
|
59
|
+
- lib/authlogic_radius.rb
|
60
|
+
- lib/authlogic_radius/acts_as_authentic.rb
|
61
|
+
- lib/authlogic_radius/session.rb
|
62
|
+
- lib/authlogic_radius/version.rb
|
63
|
+
- LICENSE
|
64
|
+
- README.rdoc
|
65
|
+
has_rdoc: true
|
66
|
+
homepage: http://github.com/bwlang/authlogic_radius
|
67
|
+
licenses: []
|
68
|
+
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options:
|
71
|
+
- --charset=UTF-8
|
72
|
+
require_paths:
|
73
|
+
- lib
|
74
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
segments:
|
86
|
+
- 0
|
87
|
+
version: "0"
|
88
|
+
requirements: []
|
89
|
+
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 1.3.6
|
92
|
+
signing_key:
|
93
|
+
specification_version: 3
|
94
|
+
summary: Extension of the Authlogic library adding RADIUS support.
|
95
|
+
test_files: []
|
96
|
+
|