adauth 1.2.1 → 2.0.0pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.travis.yml +12 -0
  2. data/Gemfile.lock +13 -26
  3. data/Rakefile +1 -0
  4. data/Readme.md +48 -0
  5. data/adauth.gemspec +2 -1
  6. data/lib/adauth.rb +40 -28
  7. data/lib/adauth/ad_object.rb +104 -0
  8. data/lib/adauth/ad_objects/computer.rb +28 -0
  9. data/lib/adauth/ad_objects/group.rb +40 -0
  10. data/lib/adauth/ad_objects/ou.rb +41 -0
  11. data/lib/adauth/ad_objects/user.rb +45 -0
  12. data/lib/adauth/authenticate.rb +25 -46
  13. data/lib/adauth/config.rb +11 -28
  14. data/lib/adauth/connection.rb +19 -18
  15. data/lib/adauth/rails.rb +9 -0
  16. data/lib/adauth/rails/helpers.rb +29 -0
  17. data/lib/adauth/rails/model_bridge.rb +59 -0
  18. data/lib/adauth/version.rb +2 -3
  19. data/lib/generators/adauth/config/config_generator.rb +1 -1
  20. data/lib/generators/adauth/config/templates/config.rb.erb +18 -22
  21. data/lib/generators/adauth/sessions/sessions_generator.rb +2 -3
  22. data/lib/generators/adauth/sessions/templates/sessions_controller.rb.erb +1 -1
  23. data/spec/adauth_ad_object_computer_spec.rb +15 -0
  24. data/spec/adauth_ad_object_group_spec.rb +21 -0
  25. data/spec/adauth_ad_object_ou_spec.rb +18 -0
  26. data/spec/adauth_ad_object_user_spec.rb +27 -0
  27. data/spec/adauth_authenticate_spec.rb +39 -0
  28. data/spec/adauth_config_spec.rb +15 -0
  29. data/spec/adauth_rails_model_bridge_spec.rb +37 -0
  30. data/spec/adauth_spec.rb +2 -30
  31. data/spec/spec_helper.rb +34 -0
  32. metadata +52 -38
  33. data/Readme.rdoc +0 -66
  34. data/lib/adauth/admin_connection.rb +0 -26
  35. data/lib/adauth/group.rb +0 -100
  36. data/lib/adauth/helpers.rb +0 -28
  37. data/lib/adauth/user.rb +0 -114
  38. data/lib/adauth/user_model.rb +0 -76
  39. data/lib/generators/adauth/all/USAGE +0 -5
  40. data/lib/generators/adauth/all/all_generator.rb +0 -18
  41. data/lib/generators/adauth/user_model/USAGE +0 -14
  42. data/lib/generators/adauth/user_model/templates/model.rb.erb +0 -3
  43. data/lib/generators/adauth/user_model/user_model_generator.rb +0 -32
  44. data/spec/adauth_group_spec.rb +0 -51
  45. data/spec/adauth_user_model_spec.rb +0 -80
  46. data/spec/adauth_user_spec.rb +0 -213
@@ -1,74 +1,53 @@
1
1
  module Adauth
2
- # Takes a username and password as an input and returns an instance of `Adauth::User`
2
+ # Authenticates the specifed user agains the domain
3
3
  #
4
- # Called as
5
- # Adauth.authenticate("Username", "Password")
6
- #
7
- # Will return `nil` if the username/password combo is wrong, if the username/password combo is correct it will return an instance of `Adauth::User` which can be used to populate your database.
8
- def self.authenticate(login, pass)
9
- if user = Adauth::User.authenticate(login, pass)
10
- return user if allowed_group_login(user) and allowed_ou_login(user)
11
- else
12
- return nil
4
+ # Checks the groups & ous are in the allow/deny lists
5
+ def self.authenticate(username, password)
6
+ begin
7
+ if Adauth::AdObjects::User.authenticate(username, password)
8
+ user = Adauth::AdObjects::User.where('sAMAccountName', username).first
9
+ if allowed_group_login(user) && allowed_ou_login(user)
10
+ return user
11
+ else
12
+ return false
13
+ end
14
+ else
15
+ return false
16
+ end
17
+ rescue RuntimeError
18
+ return false
13
19
  end
14
20
  end
15
21
 
16
- # Takes a username as an input and returns and instance of `Adauth::User`
17
- #
18
- # Called as
19
- # Adauth.authentication("Username")
20
- #
21
- # Will return `nil` if the username is worng, if the admin details are not set an error will be raised.
22
- def self.passwordless_login(login)
23
- @conn = Adauth::AdminConnection.bind
24
- if user = @conn.search(:filter => Net::LDAP::Filter.eq('sAMAccountName', login)).first
25
- return Adauth::User.new(user)
26
- else
27
- return nil
28
- end
29
- end
30
-
31
- # Checks weather an users groups are allowed to login
32
- #
33
- # Called as:
34
- # Adauth.allowed_group_login(Adauth::User)
35
- #
36
- # Returns true if the user can login and false if the user cant
22
+ # Makes sure the user meets the group requirements
37
23
  def self.allowed_group_login(user)
38
24
  if @config.allowed_groups != []
39
- allowed = (user && @config.allowed_groups != (@config.allowed_groups - user.groups)) ? user : nil
25
+ allowed = (user && @config.allowed_groups != (@config.allowed_groups - user.cn_groups)) ? user : nil
40
26
  else
41
27
  allowed = user
42
28
  end
43
-
29
+
44
30
  if @config.denied_groups != []
45
- denied = (user && @config.denied_groups == (@config.denied_groups - user.groups)) ? user : nil
31
+ denied = (user && @config.denied_groups == (@config.denied_groups - user.cn_groups)) ? user : nil
46
32
  else
47
33
  denied = user
48
34
  end
49
-
50
35
  allowed == denied
51
36
  end
52
37
 
53
- # Checks weather an users ous are allowed to login
54
- #
55
- # Called as:
56
- # Adauth.allowed_ou_login(Adauth::User)
57
- #
58
- # Returns true if the user can login and false if the user cant
38
+ # Makes sure the user meets the ou requirements
59
39
  def self.allowed_ou_login(user)
60
40
  if @config.allowed_ous != []
61
- allowed = (user && @config.allowed_ous != (@config.allowed_ous - user.ous)) ? user : nil
41
+ allowed = (user && @config.allowed_ous != (@config.allowed_ous - user.dn_ous)) ? user : nil
62
42
  else
63
43
  allowed = user
64
44
  end
65
-
45
+
66
46
  if @config.denied_ous != []
67
- denied = (user && @config.denied_ous == (@config.denied_ous - user.ous)) ? user : nil
47
+ denied = (user && @config.denied_ous == (@config.denied_ous - user.dn_ous)) ? user : nil
68
48
  else
69
49
  denied = user
70
50
  end
71
-
72
51
  allowed == denied
73
52
  end
74
- end
53
+ end
@@ -1,40 +1,23 @@
1
1
  module Adauth
2
-
3
- # Holds all of adauth config in attr_accessor values
2
+ # Holds all of Adauths Config values.
3
+ #
4
+ # Sets the defaults an create and generates guess values.
4
5
  class Config
5
- attr_accessor :domain, :port, :base, :server, :allowed_groups, :denied_groups, :ad_sv_attrs, :ad_mv_attrs, :allowed_ous, :denied_ous,
6
- :admin_user, :admin_password, :ad_sv_group_attrs, :ad_mv_group_attrs
6
+ attr_accessor :domain, :port, :base, :server, :encryption, :query_user, :query_password,
7
+ :allowed_groups, :denied_groups, :allowed_ous, :denied_ous
7
8
 
8
- # Creates a new instance of Adauth::Config
9
- #
10
- # Sets port, allowed_groups, denied_groups, ad_sv_attrs and ad_mv_attrs to default so they can be omitted from the config
11
9
  def initialize
12
- @port = 389
13
- @allowed_groups = []
14
- @denied_groups = []
15
- @ad_sv_attrs = {}
16
- @ad_mv_attrs = {}
17
- @allowed_ous = []
18
- @denied_ous = []
19
- @ad_sv_group_attrs = {}
20
- @ad_mv_group_attrs = {}
10
+ @port = 389
11
+ @allowed_groups = []
12
+ @allowed_ous = []
13
+ @denied_groups =[]
14
+ @denied_ous = []
21
15
  end
22
16
 
23
- # Sets domain valiable
24
- #
25
- # Called as:
26
- # Adauth::Config.domain=(s)
27
- #
28
- # Calculates both base string and server
17
+ # Guesses the Server and Base string
29
18
  def domain=(s)
30
19
  @domain = s
31
- work_out_base(s)
32
20
  @server ||= s
33
- end
34
-
35
- private
36
-
37
- def work_out_base(s)
38
21
  @base ||= s.gsub(/\./,', dc=').gsub(/^/,"dc=")
39
22
  end
40
23
  end
@@ -1,32 +1,33 @@
1
1
  module Adauth
2
-
3
- # Create a connection to LDAP using Net::LDAP
2
+ # Active Directory Connection wrapper
4
3
  #
5
- # Called as:
6
- # Adauth::Connection.bind(username, password)
7
- #
8
- #
4
+ # Handles errors and configures the connection.
9
5
  class Connection
6
+ def initialize(config)
7
+ @config = config
8
+ end
10
9
 
11
- # Create a connection to LDAP using Net::LDAP
10
+ # Attempts to bind to Active Directory
12
11
  #
13
- # Called as:
14
- # Adauth::Connection.bind(username, password)
12
+ # If it works it returns the connection
15
13
  #
16
- #
17
- def self.bind(login, pass)
18
- conn = Net::LDAP.new :host => Adauth.config.server,
19
- :port => Adauth.config.port,
20
- :base => Adauth.config.base,
21
- :auth => { :username => "#{login}@#{Adauth.config.domain}",
22
- :password => pass,
23
- :method => :simple }
14
+ # If it fails it raises and exception
15
+ def bind
16
+ conn = Net::LDAP.new :host => @config[:server],
17
+ :port => @config[:port],
18
+ :base => @config[:base]
19
+ if @config[:encryption]
20
+ conn.encryption = @config[:encryption]
21
+ end
22
+
23
+ conn.auth "#{@config[:username]}@#{@config[:domain]}", @config[:password]
24
+
24
25
  begin
25
26
  Timeout::timeout(10){
26
27
  if conn.bind
27
28
  return conn
28
29
  else
29
- return nil
30
+ raise "Query User Rejected"
30
31
  end
31
32
  }
32
33
  rescue Timeout::Error
@@ -0,0 +1,9 @@
1
+ module Adauth
2
+ # Container for Rails te-ins
3
+ module Rails
4
+ end
5
+
6
+ # Rails generators
7
+ module Generators
8
+ end
9
+ end
@@ -0,0 +1,29 @@
1
+ module Adauth
2
+ module Rails
3
+ # Helper methods for rails
4
+ module Helpers
5
+
6
+ # Creates a form_tag for the adauth form
7
+ #
8
+ # Sets the html id to "adauth_login" and the form destination to "/adauth"
9
+ def adauth_form
10
+ form_tag '/adauth', :id => "adauth_login" do
11
+ yield.html_safe
12
+ end
13
+ end
14
+
15
+ # Create the default form by calling `adauth_form` and passing a username and password input
16
+ def default_adauth_form
17
+ adauth_form do
18
+ "<p>#{label_tag :username}:
19
+ #{text_field_tag :username}</p>
20
+ <p>#{label_tag :password}:
21
+ #{password_field_tag :password}</p>
22
+ <p>#{submit_tag "Login!"}</p>"
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ ActionView::Base.send :include, Adauth::Rails::Helpers if defined? ActionView
@@ -0,0 +1,59 @@
1
+ module Adauth
2
+ module Rails
3
+ # Included into Models in Rails
4
+ #
5
+ # Requires you to set 2 Constants
6
+ #
7
+ # AdauthMappings
8
+ #
9
+ # A hash which controls how Adauth maps its values to rails e.g.
10
+ #
11
+ # AdauthMappings = {
12
+ # :name => :login
13
+ # }
14
+ #
15
+ # This will store Adauths 'login' value in the 'name' field.
16
+ #
17
+ # AdauthSearchField
18
+ #
19
+ # This is an array which contains 2 values and is used to find the objects record e.g.
20
+ #
21
+ # AdauthSearchField = [:login, :name]
22
+ #
23
+ # This will cause RailsModel.find_by_name(AdauthObject.login)
24
+ #
25
+ # The Order is [adauth_field, rails_field]
26
+ module ModelBridge
27
+ # Registers the class methods when ModelBridge is included
28
+ def self.included(base)
29
+ base.extend ClassMethods
30
+ end
31
+
32
+ # Uses AdauthMappings to update the values on the model using the ones from Adauth
33
+ def update_from_adauth(adauth_model)
34
+ self.class::AdauthMappings.each do |k, v|
35
+ setter = "#{k.to_s}=".to_sym
36
+ self.send(setter, adauth_model.send(v))
37
+ end
38
+ self.save
39
+ end
40
+
41
+ # Class Methods for ModelBridge
42
+ module ClassMethods
43
+ # Creates a new RailsModel from the adauth_model
44
+ def create_from_adauth(adauth_model)
45
+ rails_model = self.new
46
+ rails_model.update_from_adauth(adauth_model)
47
+ end
48
+
49
+ # Used to create the RailsModel if it doesn't exist and update it if it does
50
+ def return_and_create_from_adauth(adauth_model)
51
+ find_method = "find_by_#{self::AdauthSearchField.last}".to_sym
52
+ rails_model = (self.send(find_method, adauth_model.send(self::AdauthSearchField.first)) || create_from_adauth(adauth_model))
53
+ rails_model.update_from_adauth(adauth_model)
54
+ return rails_model
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,5 +1,4 @@
1
1
  module Adauth
2
-
3
- # The version of the gem
4
- Version = "1.2.1"
2
+ # Adauths Version Number
3
+ Version = "2.0.0pre"
5
4
  end
@@ -2,7 +2,7 @@ module Adauth
2
2
  module Generators
3
3
 
4
4
  # Generates a sample config file
5
- class ConfigGenerator < Rails::Generators::Base
5
+ class ConfigGenerator < ::Rails::Generators::Base
6
6
  source_root File.expand_path('../templates', __FILE__)
7
7
 
8
8
  # Generates a sample config file
@@ -5,53 +5,49 @@ Adauth.configure do |c|
5
5
  #
6
6
  # If you don't know your domain contact your IT support,
7
7
  # it will be the DNS suffix applied to your machines
8
- c.domain = "example.com"
9
-
8
+ c.domain = "example.com"
9
+
10
+ # Adauth needs a query user to interact with the domain.
11
+ # This user can be anything with domain access
12
+ #
13
+ # If Adauth doesn't work contact your IT support and make sure this account has full query access
14
+ c.query_user = "username"
15
+ c.query_password = "password"
16
+
10
17
  # The IP address or Hostname of a DC (Domain Controller) on your network
11
18
  #
12
19
  # This could be anything and probably wont be 127.0.0.1
13
20
  #
14
21
  # Again contact your IT Support if you can't work this out
15
22
  c.server = "127.0.0.1"
16
-
23
+
17
24
  # The LDAP base of your domain/intended users
18
25
  #
19
26
  # For all users in your domain the base would be:
20
27
  # dc=example, dc=com
21
28
  # OUs can be prepeneded to restrict access to your app
22
29
  c.base = "dc=example, dc=com"
23
-
30
+
24
31
  # The port isn't always needed as Adauth defaults to 389 the LDAP Port
25
32
  #
26
33
  # If your DC is on the other side of a firewall you may need to change the port
34
+ # If your DC is using SSL, the port may be 636.
27
35
  #c.port = 389
28
-
36
+
37
+ # If your DC is using SSL, set encryption to :simple_tls
38
+ #c.encryption = :simple_tls
39
+
29
40
  # Windows Security groups to allow
30
41
  #
31
42
  # Only allow members of set windows security groups to login
32
- #
43
+ #
33
44
  # Takes an array for group names
34
45
  #c.allowed_groups = ["Group1", "Group2"]
35
-
46
+
36
47
  # Windows Security groups to deny
37
48
  #
38
49
  # Only allow users who aren't in these groups to login
39
50
  #
40
51
  # Takes an array for group names
41
52
  #c.denied_groups = ["Group1", "Group2"]
42
-
43
- # Additional single attributes to fetch
44
- #
45
- # Single Values to fetch from Active Directory for example phone number
46
- #
47
- # Takes a hash in the form { :method_on_Adauth::User => :field_in_ad }
48
- #c.ad_sv_attrs = { :phone => :telephonenumber }
49
-
50
- # Additional multi attributes to fetch
51
- #
52
- # Multiple Values to fetch from Active Directory
53
- #
54
- # Takes a hash in the form { :method_on_Adauth::User => [ :field_in_ad, Proc.new { |g| operations_to_turn_field_into_array } ] }
55
- # Example os for groups (already provided)
56
- #c.ad_mv_attrs(:groups => [ :memberof, Proc.new {|g| g.sub(/.*?CN=(.*?),.*/, '\1')} ])
57
53
  end
@@ -1,8 +1,7 @@
1
1
  module Adauth
2
2
  module Generators
3
-
4
3
  # Generates the sessions controller
5
- class SessionsGenerator < Rails::Generators::Base
4
+ class SessionsGenerator < ::Rails::Generators::Base
6
5
  source_root File.expand_path('../templates', __FILE__)
7
6
  argument :model_name, :type => :string, :default => "user"
8
7
 
@@ -28,4 +27,4 @@ module Adauth
28
27
  end
29
28
  end
30
29
  end
31
- end
30
+ end
@@ -6,7 +6,7 @@ class SessionsController < ApplicationController
6
6
  def create
7
7
  ldap_user = Adauth.authenticate(params[:username], params[:password])
8
8
  if ldap_user
9
- user = <%= model_name.camelize %>.return_and_create_with_adauth(ldap_user)
9
+ user = <%= model_name.camelize %>.return_and_create_from_adauth(ldap_user)
10
10
  session[:user_id] = user.id
11
11
  redirect_to root_path
12
12
  else
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ describe Adauth::AdObjects::Computer do
4
+ it "Should find a computer" do
5
+ default_config
6
+ pdc.should be_a Adauth::AdObjects::Computer
7
+ end
8
+
9
+ it "should be in an ou" do
10
+ default_config
11
+ pdc.ous.should be_a Array
12
+ pdc.ous.first.should be_a Adauth::AdObjects::OU
13
+ pdc.ous.first.name.should eq "Domain Controllers"
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Adauth::AdObjects::Group do
4
+ it "should have a name" do
5
+ default_config
6
+ group = domain_admins
7
+ group.name.should eq "Domain Admins"
8
+ end
9
+
10
+ it "should have a members list" do
11
+ default_config
12
+ group = domain_admins
13
+ group.members.first.name.should be_a String
14
+ end
15
+
16
+ it "should be a member of" do
17
+ default_config
18
+ group = domain_admins
19
+ group.groups.should be_a Array
20
+ end
21
+ end