authentasaurus 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (116) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +173 -0
  3. data/TODO +4 -0
  4. data/app/controllers/areas_controller.rb +4 -0
  5. data/app/controllers/groups_controller.rb +4 -0
  6. data/app/controllers/permissions_controller.rb +4 -0
  7. data/app/controllers/recoveries_controller.rb +2 -0
  8. data/app/controllers/registrations_controller.rb +2 -0
  9. data/app/controllers/sessions_controller.rb +2 -0
  10. data/app/controllers/user_invitations_controller.rb +4 -0
  11. data/app/controllers/users_controller.rb +4 -0
  12. data/app/controllers/validations_controller.rb +2 -0
  13. data/app/models/area.rb +2 -0
  14. data/app/models/authentasaurus_emailer.rb +2 -0
  15. data/app/models/group.rb +2 -0
  16. data/app/models/permission.rb +2 -0
  17. data/app/models/recovery.rb +2 -0
  18. data/app/models/session.rb +2 -0
  19. data/app/models/user.rb +3 -0
  20. data/app/models/user_invitation.rb +2 -0
  21. data/app/models/user_sync.rb +3 -0
  22. data/app/models/validation.rb +2 -0
  23. data/app/views/areas/edit.html.erb +7 -0
  24. data/app/views/areas/index.html.erb +11 -0
  25. data/app/views/areas/new.html.erb +7 -0
  26. data/app/views/areas/show.html.erb +7 -0
  27. data/app/views/authentasaurus_emailer/invitation_mail.html.erb +4 -0
  28. data/app/views/authentasaurus_emailer/recovery_mail.html.erb +7 -0
  29. data/app/views/authentasaurus_emailer/validation_mail.html.erb +6 -0
  30. data/app/views/groups/edit.html.erb +7 -0
  31. data/app/views/groups/index.html.erb +11 -0
  32. data/app/views/groups/new.html.erb +7 -0
  33. data/app/views/groups/show.html.erb +7 -0
  34. data/app/views/permissions/edit.html.erb +19 -0
  35. data/app/views/permissions/index.html.erb +17 -0
  36. data/app/views/permissions/new.html.erb +19 -0
  37. data/app/views/permissions/show.html.erb +7 -0
  38. data/app/views/recoveries/edit.html.erb +24 -0
  39. data/app/views/recoveries/new.html.erb +15 -0
  40. data/app/views/registrations/new.html.erb +21 -0
  41. data/app/views/sessions/new.html.erb +41 -0
  42. data/app/views/sessions/no_access.html.erb +1 -0
  43. data/app/views/user_invitations/index.html.erb +14 -0
  44. data/app/views/user_invitations/new.html.erb +9 -0
  45. data/app/views/users/edit.html.erb +27 -0
  46. data/app/views/users/index.html.erb +19 -0
  47. data/app/views/users/new.html.erb +27 -0
  48. data/app/views/users/show.html.erb +11 -0
  49. data/app/views/validations/activate.html.erb +6 -0
  50. data/app/views/validations/resend_validation_email.html.erb +6 -0
  51. data/config/locales/en.yml +34 -0
  52. data/generators/authentasaurus/USAGE +2 -0
  53. data/generators/authentasaurus/authentasaurus_generator.rb +9 -0
  54. data/generators/authentasaurus/templates/authentasaurus_tasks.rake +48 -0
  55. data/generators/authentasaurus/templates/defaults.yml +51 -0
  56. data/generators/authentasaurus/templates/initializer.rb +3 -0
  57. data/generators/authentasaurus_views/USAGE +12 -0
  58. data/generators/authentasaurus_views/authentasaurus_views_generator.rb +87 -0
  59. data/generators/authentasaurus_views/templates/views/areas/edit.html.erb +7 -0
  60. data/generators/authentasaurus_views/templates/views/areas/index.html.erb +11 -0
  61. data/generators/authentasaurus_views/templates/views/areas/new.html.erb +7 -0
  62. data/generators/authentasaurus_views/templates/views/areas/show.html.erb +7 -0
  63. data/generators/authentasaurus_views/templates/views/authentasaurus_emailer/invitation_mail.html.erb +4 -0
  64. data/generators/authentasaurus_views/templates/views/authentasaurus_emailer/recovery_mail.html.erb +7 -0
  65. data/generators/authentasaurus_views/templates/views/authentasaurus_emailer/validation_mail.html.erb +6 -0
  66. data/generators/authentasaurus_views/templates/views/groups/edit.html.erb +7 -0
  67. data/generators/authentasaurus_views/templates/views/groups/index.html.erb +11 -0
  68. data/generators/authentasaurus_views/templates/views/groups/new.html.erb +7 -0
  69. data/generators/authentasaurus_views/templates/views/groups/show.html.erb +7 -0
  70. data/generators/authentasaurus_views/templates/views/permissions/edit.html.erb +19 -0
  71. data/generators/authentasaurus_views/templates/views/permissions/index.html.erb +17 -0
  72. data/generators/authentasaurus_views/templates/views/permissions/new.html.erb +19 -0
  73. data/generators/authentasaurus_views/templates/views/permissions/show.html.erb +7 -0
  74. data/generators/authentasaurus_views/templates/views/recoveries/edit.html.erb +24 -0
  75. data/generators/authentasaurus_views/templates/views/recoveries/new.html.erb +15 -0
  76. data/generators/authentasaurus_views/templates/views/registrations/new.html.erb +21 -0
  77. data/generators/authentasaurus_views/templates/views/sessions/new.html.erb +41 -0
  78. data/generators/authentasaurus_views/templates/views/sessions/no_access.html.erb +1 -0
  79. data/generators/authentasaurus_views/templates/views/user_invitations/index.html.erb +14 -0
  80. data/generators/authentasaurus_views/templates/views/user_invitations/new.html.erb +9 -0
  81. data/generators/authentasaurus_views/templates/views/users/edit.html.erb +27 -0
  82. data/generators/authentasaurus_views/templates/views/users/index.html.erb +19 -0
  83. data/generators/authentasaurus_views/templates/views/users/new.html.erb +27 -0
  84. data/generators/authentasaurus_views/templates/views/users/show.html.erb +11 -0
  85. data/generators/authentasaurus_views/templates/views/validations/activate.html.erb +6 -0
  86. data/generators/authentasaurus_views/templates/views/validations/resend_validation_email.html.erb +6 -0
  87. data/lib/action_controller/authorization.rb +215 -0
  88. data/lib/action_view/authorization.rb +123 -0
  89. data/lib/active_record/acts_as_authenticatable.rb +80 -0
  90. data/lib/active_record/acts_as_authenticatable_validatable.rb +32 -0
  91. data/lib/active_record/authenticatable.rb +56 -0
  92. data/lib/active_resource/acts_as_authenticatable.rb +42 -0
  93. data/lib/active_resource/authenticatable.rb +22 -0
  94. data/lib/authentasaurus.rb +21 -0
  95. data/lib/authentasaurus/areas_controller.rb +71 -0
  96. data/lib/authentasaurus/authentasaurus_controller.rb +2 -0
  97. data/lib/authentasaurus/groups_controller.rb +73 -0
  98. data/lib/authentasaurus/models/area.rb +8 -0
  99. data/lib/authentasaurus/models/authentasaurus_emailer.rb +31 -0
  100. data/lib/authentasaurus/models/group.rb +8 -0
  101. data/lib/authentasaurus/models/permission.rb +9 -0
  102. data/lib/authentasaurus/models/recovery.rb +23 -0
  103. data/lib/authentasaurus/models/session.rb +63 -0
  104. data/lib/authentasaurus/models/user_invitation.rb +21 -0
  105. data/lib/authentasaurus/models/validation.rb +18 -0
  106. data/lib/authentasaurus/permissions_controller.rb +71 -0
  107. data/lib/authentasaurus/recoveries_controller.rb +59 -0
  108. data/lib/authentasaurus/registrations_controller.rb +32 -0
  109. data/lib/authentasaurus/sessions_controller.rb +45 -0
  110. data/lib/authentasaurus/user_invitations_controller.rb +39 -0
  111. data/lib/authentasaurus/users_controller.rb +71 -0
  112. data/lib/authentasaurus/validations_controller.rb +34 -0
  113. data/lib/helpers/migrations.rb +171 -0
  114. data/lib/helpers/routing.rb +90 -0
  115. data/rails/init.rb +37 -0
  116. metadata +188 -0
@@ -0,0 +1,123 @@
1
+ # Defines authorization helpers for ActionController
2
+ module ActionView::Authorization
3
+
4
+ def self.included(base) # :nodoc:
5
+ base.send :include, InstanceMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ private
10
+ # Returns an object of the current user
11
+ def current_user(user_model = nil)
12
+ user_model = User if user_model.nil?
13
+ return user_model.find session[:user_id] if session[:user_id]
14
+ end
15
+
16
+ # Checks if the current user is logged in and redirects to the login path if the user is not logged in.
17
+ #
18
+ # If skip_request is set to true, the user won't be redirected to the original url after he/she logs in.
19
+ def check_logged_in(skip_request = false, user_model = nil)
20
+ unless is_logged_in?(user_model)
21
+ login_required skip_request
22
+ end
23
+ end
24
+
25
+ # Checks if the current user is logged in and has write permission over the current controller, redirects to no access
26
+ # page if the user hasn't the permissions and redirects to the login path if the user is not logged in
27
+ #
28
+ # If skip_request is set to true, the user won't be redirected to the original url after he/she logs in.
29
+ def check_write_permissions(skip_request = false, user_model = nil)
30
+ if is_logged_in?(user_model)
31
+ user_permissions = session[:user_permissions]
32
+ check = user_permissions[:write].find { |perm| perm==self.controller_name || perm=="all" }
33
+ unless check
34
+ redirect_to no_access_sessions_path
35
+ end
36
+ else
37
+ login_required skip_request
38
+ end
39
+ end
40
+
41
+ # Checks if the current user is logged in and has read permission over the current controller, redirects to no access
42
+ # page if the user hasn't the permissions and redirects to the login path if the user is not logged in
43
+ #
44
+ # If skip_request is set to true, the user won't be redirected to the original url after he/she logs in.
45
+ def check_read_permissions(skip_request = false, user_model = nil)
46
+ if is_logged_in?(user_model)
47
+ user_permissions = session[:user_permissions]
48
+ check = user_permissions[:read].find { |perm| perm==self.controller_name || perm=="all" }
49
+ unless check
50
+ redirect_to no_access_sessions_path
51
+ end
52
+ else
53
+ login_required skip_request
54
+ end
55
+ end
56
+
57
+ # Checks if the current user is logged in but takes no further action
58
+ def is_logged_in?(user_model)
59
+ user_model = User if user_model.nil?
60
+ unless user_model.find_by_id(session[:user_id])
61
+ return cookie_login?(user_model)
62
+ end
63
+ return true
64
+ end
65
+
66
+ # Logs in the user through a remember me cookie
67
+ def cookie_login?(user_model)
68
+ user_model = User if user_model.nil?
69
+
70
+ if cookies[:remember_me_token]
71
+ user = user_model.find_by_remember_me_token cookies[:remember_me_token]
72
+ if user.nil?
73
+ cookies.delete :remember_me_token
74
+ return false
75
+ else
76
+ session[:user_id] = user.id
77
+ session[:user_permissions] = {:read => user.permissions.collect{|per| per.area.name if per.read}, :write => user.permissions.collect{|per| per.area.name if per.write}}
78
+ return true
79
+ end
80
+ else
81
+ return false
82
+ end
83
+ end
84
+
85
+ # Redirects the user to the login page
86
+ #
87
+ # If skip_request is set to true, the user won't be redirected to the original url after he/she logs in.
88
+ def login_required(skip_request)
89
+ unless(skip_request)
90
+ session[:original_url]=request.url
91
+ end
92
+ flash[:notice] = t(:login_required, :scope => [:authentasaurus, :action_controller, :errors, :messages])
93
+ redirect_to new_session_path
94
+ end
95
+
96
+ # Checks if the current user has the appropriate permission
97
+ #
98
+ # *ex*: has?(:write) or has?(:read, :users)
99
+ def has?(permission, area = nil, user_model = User)
100
+ return false unless is_logged_in? user_model
101
+ check = false
102
+ case permission
103
+ when :write
104
+ unless area
105
+ user_permissions = session[:user_permissions]
106
+ check = user_permissions[:write].find { |perm| perm==self.controller_name || perm=="all" }
107
+ else
108
+ user_permissions = session[:user_permissions]
109
+ check = user_permissions[:write].find { |perm| perm==area.to_s || perm=="all" }
110
+ end
111
+ when :read
112
+ unless area
113
+ user_permissions = session[:user_permissions]
114
+ check = user_permissions[:read].find { |perm| perm==self.controller_name || perm=="all" }
115
+ else
116
+ user_permissions = session[:user_permissions]
117
+ check = user_permissions[:read].find { |perm| perm==area.to_s || perm=="all" }
118
+ end
119
+ end
120
+ return check
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,80 @@
1
+ module ActiveRecord::ActsAsAuthenticatable
2
+ def self.included(base)
3
+ base.send :extend, ClassMethods
4
+ base.send :include, InstanceMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ require 'digest/sha1'
9
+ ## Authenticates the username and password
10
+ def authenticate(username, password)
11
+ user=self.find_by_username username
12
+ if user
13
+ expected_password=encrypt_password(password, user.password_seed)
14
+ user = nil unless expected_password == user.hashed_password && user.active
15
+ end
16
+ return user
17
+ end
18
+
19
+ ## Encrypts the password using the given seed
20
+ def encrypt_password(password, password_seed)
21
+ pass_to_hash=password + "Securasaurus" + password_seed
22
+ Digest::SHA1.hexdigest(pass_to_hash)
23
+ end
24
+ end
25
+
26
+ module InstanceMethods
27
+ ## Password attribute (used when creating a user)
28
+ def password
29
+ return @password
30
+ end
31
+
32
+ def password=(pwd)
33
+ @password = pwd
34
+ return if pwd.blank?
35
+ create_salt
36
+ self.hashed_password = self.class.encrypt_password(@password, self.password_seed)
37
+ end
38
+
39
+ ## New password attribute (used when editing a user)
40
+ def new_password
41
+ return @new_password
42
+ end
43
+
44
+ def new_password=(pwd)
45
+ @new_password = pwd
46
+ return if pwd.blank?
47
+ create_salt
48
+ self.hashed_password = self.class.encrypt_password(@new_password, self.password_seed)
49
+ end
50
+
51
+ def activate
52
+ self.update_attribute :active, true
53
+ end
54
+
55
+ def deactivate
56
+ self.update_attribute :active, false
57
+ end
58
+
59
+ def create_remember_me_token
60
+ pass_to_hash=Time.now.to_i.to_s + "Securasaurus" + password_seed
61
+ self.update_attribute :remember_me_token, Digest::SHA1.hexdigest(pass_to_hash)
62
+ self.remember_me_token
63
+ end
64
+
65
+ private
66
+ def new_password_blank?
67
+ self.new_password.blank?
68
+ end
69
+
70
+ ## Creates password seed (salt)
71
+ def create_salt
72
+ self.password_seed = self.object_id.to_s + rand.to_s
73
+ end
74
+
75
+ ## Dont delete the last user
76
+ def dont_delete_admin
77
+ raise "You cannot delete the last admin" if self.id == 1 || User.count == 1
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,32 @@
1
+ module ActiveRecord::ActsAsAuthenticatableValidatable
2
+ def self.included(base)
3
+ base.send :extend, ActiveRecord::ActsAsAuthenticatable::ClassMethods
4
+ base.send :include, ActiveRecord::ActsAsAuthenticatable::InstanceMethods
5
+ base.send :extend, ClassMethods
6
+ base.send :include, InstanceMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ ## Authenticates the username and password
11
+ def authenticate(username, password)
12
+ user=self.find_by_username username
13
+ if user
14
+ expected_password=encrypt_password(password, user.password_seed)
15
+ user = nil unless expected_password == user.hashed_password && user.active && user.validation.nil?
16
+ end
17
+ return user
18
+ end
19
+ end
20
+
21
+ module InstanceMethods
22
+ private
23
+ def create_validation
24
+ unless self.active
25
+ validation = Validation.new(:user => self, :email => self.email, :validation_code => User.encrypt_password(self.username,self.password_seed))
26
+ unless validation.save
27
+ raise "Could not create validation record"
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,56 @@
1
+ module ActiveRecord::Authenticatable
2
+ def self.included(base)
3
+ base.send :extend, ClassMethods
4
+ end
5
+
6
+ module ClassMethods
7
+ def authenticatable(*args)
8
+ options = args.extract_options!
9
+ args = args.flatten
10
+ # Associations
11
+ belongs_to :group
12
+ has_many :permissions, :through => :group
13
+ # Validation
14
+ # basic attributes
15
+ validates_presence_of :username, :hashed_password, :password_seed, :email, :name
16
+ validates_uniqueness_of :username, :email
17
+ validates_format_of :email, :with => %r{[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}}
18
+ # password validations
19
+ validates_confirmation_of :password, :on => :create
20
+ validates_presence_of :password, :on => :create
21
+ validates_length_of :password, :minimum => 6, :on => :create
22
+ # new password
23
+ validates_confirmation_of :new_password, :on => :update, :unless => :new_password_blank?
24
+ validates_length_of :new_password, :minimum => 6, :on => :update, :unless => :new_password_blank?
25
+ # format of password
26
+ if args.include?(:strong_password)
27
+ validates_format_of :password, :with => %r{[a-z]}, :on => :create, :message => :"authenticatable.lower_case_password"
28
+ validates_format_of :password, :with => %r{[A-Z]}, :on => :create, :message => :"authenticatable.upper_case_password"
29
+ validates_format_of :password, :with => %r{[0-9]}, :on => :create, :message => :"authenticatable.digit_password"
30
+ validates_format_of :password, :with => %r{[@$%!&]}, :on => :create, :message => :"authenticatable.symbol_password"
31
+ # new password
32
+ validates_format_of :new_password, :with => %r{[a-z]}, :on => :update, :message => :"authenticatable.lower_case_password", :unless => :new_password_blank?
33
+ validates_format_of :new_password, :with => %r{[A-Z]}, :on => :update, :message => :"authenticatable.upper_case_password", :unless => :new_password_blank?
34
+ validates_format_of :new_password, :with => %r{[0-9]}, :on => :update, :message => :"authenticatable.digit_password", :unless => :new_password_blank?
35
+ validates_format_of :new_password, :with => %r{[@$%!&]}, :on => :update, :message => :"authenticatable.symbol_password", :unless => :new_password_blank?
36
+ end
37
+
38
+ # Accessors
39
+ attr_accessor :password_confirmation, :new_password_confirmation
40
+
41
+ # dont delete admin
42
+ before_destroy :dont_delete_admin
43
+
44
+ #validation
45
+ if args.include?(:validatable)
46
+ has_one :validation, :as => :user
47
+ before_create :create_validation
48
+ # include authentication methods including validation
49
+ include ActiveRecord::ActsAsAuthenticatableValidatable
50
+ else
51
+ # include authentication methods
52
+ include ActiveRecord::ActsAsAuthenticatable
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,42 @@
1
+ module ActiveResource::ActsAsAuthenticatable
2
+ def self.included(base)
3
+ base.send :extend, ClassMethods
4
+ base.send :include, InstanceMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ ## Authenticates the username and password
9
+ def authenticate(username, password)
10
+
11
+ if self.sync_to
12
+ user = self.new Hash.from_xml(self.post(:signin,:username => username, :password => password).body).values.first
13
+ end
14
+
15
+ unless user.nil?
16
+ if self.sync && !self.sync_to.nil?
17
+ last_update = user.attributes.delete "updated_at"
18
+ local_user = self.sync_to.find_or_initialize_by_username user.username, user.attributes
19
+
20
+ if local_user.updated_at < last_update
21
+ local_user.update_attributes user.attributes
22
+ end
23
+ end
24
+ end
25
+ return user
26
+ end
27
+ end
28
+
29
+ module InstanceMethods
30
+ def sync
31
+ if self.class.sync && !self.class.sync_to.nil?
32
+ user = self.dup
33
+ last_update = user.attributes.delete "updated_at"
34
+ local_user = self.class.sync_to.find_or_initialize_by_username user.username, user.attributes
35
+
36
+ local_user.update_attributes user.attributes
37
+ else
38
+ false
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,22 @@
1
+ require 'active_resource/acts_as_authenticatable'
2
+ module ActiveResource::Authenticatable
3
+ def self.included(base)
4
+ base.send :extend, ClassMethods
5
+ end
6
+
7
+ module ClassMethods
8
+
9
+ def authenticatable(*args)
10
+ options = args.extract_options!
11
+
12
+ self.site = options[:site] || AUTHENTASAURUS[:modules][:remote][self.name.underscore.gsub(/_sync/, "").to_sym][:site]
13
+ self.element_name = options[:session_element].try(:to_s) || AUTHENTASAURUS[:modules][:remote][self.name.underscore.gsub(/_sync/, "").to_sym][:session_element]
14
+ self.sync = options[:sync] || AUTHENTASAURUS[:modules][:remote][self.name.underscore.gsub(/_sync/, "").to_sym][:sync]
15
+ self.sync_to = options[:sync_to].try(:to_s).try(:camelize).try(:constantize) #|| AUTHENTASAURUS[:modules][:remote][self.name.underscore.gsub(/_sync/, "").to_sym][:sync_to].camelize.constantize
16
+
17
+
18
+ # include authentication methods
19
+ include ActiveResource::ActsAsAuthenticatable
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module Authentasaurus
2
+ def self.evaluate_method(method, *args, &block)
3
+ case method
4
+ when Symbol
5
+ object = args.shift
6
+ object.send(method, *args, &block)
7
+ when String
8
+ eval(method, args.first.instance_eval { binding })
9
+ when Proc, Method
10
+ method.call(*args, &block)
11
+ else
12
+ if method == true || method == false
13
+ return method
14
+ else
15
+ raise ArgumentError,
16
+ "Callbacks must be a symbol denoting the method to call, a string to be evaluated, " +
17
+ "a block to be invoked, or a condition."
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,71 @@
1
+ class Authentasaurus::AreasController < Authentasaurus::AuthentasaurusController
2
+
3
+ def index
4
+ @areas= Area.find :all
5
+
6
+ respond_to do |format|
7
+ format.html
8
+ end
9
+ end
10
+
11
+ def show
12
+ @area = Area.find params[:id]
13
+
14
+ respond_to do |format|
15
+ format.html
16
+ end
17
+ end
18
+
19
+ def new
20
+ @area = Area.new
21
+
22
+ respond_to do |format|
23
+ format.html
24
+ end
25
+ end
26
+
27
+ def create
28
+ @area = Area.new params[:area]
29
+
30
+ respond_to do |format|
31
+ if @area.save
32
+ flash.now[:notice] = "Area created"
33
+ format.html { redirect_to :action=>:index }
34
+ else
35
+ flash.now[:notice] = "Error creating area"
36
+ format.html { render :new }
37
+ end
38
+ end
39
+ end
40
+
41
+ def edit
42
+ @area = Area.find params[:id]
43
+
44
+ respond_to do |format|
45
+ format.html
46
+ end
47
+ end
48
+
49
+ def update
50
+ @area = Area.find params[:id]
51
+
52
+ respond_to do |format|
53
+ if @area.update_attributes(params[:area])
54
+ flash.now[:notice] = "Area updated"
55
+ format.html { redirect_to @area }
56
+ else
57
+ flash.now[:notice] = "Error updating area"
58
+ format.html { render :edit }
59
+ end
60
+ end
61
+ end
62
+
63
+ def destroy
64
+ @area = Area.find params[:id]
65
+ @area.destroy
66
+
67
+ respond_to do |format|
68
+ format.html { redirect_to :action=>:index }
69
+ end
70
+ end
71
+ end