authengine 0.0.2

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.
Files changed (155) hide show
  1. data/.gitignore +10 -0
  2. data/.rspec +1 -0
  3. data/Gemfile +4 -0
  4. data/README.md +86 -0
  5. data/Rakefile +31 -0
  6. data/app/assets/images/message_block/back.gif +0 -0
  7. data/app/assets/images/message_block/back_m.gif +0 -0
  8. data/app/assets/images/message_block/confirmation.gif +0 -0
  9. data/app/assets/images/message_block/confirmation_m.gif +0 -0
  10. data/app/assets/images/message_block/error.gif +0 -0
  11. data/app/assets/images/message_block/error_m.gif +0 -0
  12. data/app/assets/images/message_block/info.gif +0 -0
  13. data/app/assets/images/message_block/info_m.gif +0 -0
  14. data/app/assets/images/message_block/notice.gif +0 -0
  15. data/app/assets/images/message_block/notice_m.gif +0 -0
  16. data/app/assets/images/message_block/warn.gif +0 -0
  17. data/app/assets/images/message_block/warn_m.gif +0 -0
  18. data/app/assets/stylesheets/authengine.css +3 -0
  19. data/app/assets/stylesheets/message_block.css +45 -0
  20. data/app/controllers/authengine/accounts_controller.rb +56 -0
  21. data/app/controllers/authengine/action_roles_controller.rb +22 -0
  22. data/app/controllers/authengine/actions_controller.rb +17 -0
  23. data/app/controllers/authengine/roles_controller.rb +35 -0
  24. data/app/controllers/authengine/sessions_controller.rb +75 -0
  25. data/app/controllers/authengine/user_roles_controller.rb +55 -0
  26. data/app/controllers/authengine/useractions_controller.rb +17 -0
  27. data/app/controllers/authengine/users_controller.rb +137 -0
  28. data/app/helpers/application_helper.rb +2 -0
  29. data/app/helpers/authengine/users_helper.rb +11 -0
  30. data/app/helpers/roles_helper.rb +2 -0
  31. data/app/mailers/authengine/user_mailer.rb +53 -0
  32. data/app/models/action.rb +54 -0
  33. data/app/models/action_role.rb +29 -0
  34. data/app/models/authenticated_system.rb +179 -0
  35. data/app/models/authorized_system.rb +41 -0
  36. data/app/models/controller.rb +124 -0
  37. data/app/models/role.rb +71 -0
  38. data/app/models/session.rb +3 -0
  39. data/app/models/session_role.rb +17 -0
  40. data/app/models/user.rb +191 -0
  41. data/app/models/user_observer.rb +14 -0
  42. data/app/models/user_role.rb +4 -0
  43. data/app/models/useraction.rb +56 -0
  44. data/app/views/authengine/accounts/edit.html.erb +19 -0
  45. data/app/views/authengine/actions/create.html.erb +2 -0
  46. data/app/views/authengine/actions/destroy.html.erb +2 -0
  47. data/app/views/authengine/actions/edit.html.erb +80 -0
  48. data/app/views/authengine/actions/index.html.haml +26 -0
  49. data/app/views/authengine/actions/new.html.erb +2 -0
  50. data/app/views/authengine/actions/show.html.erb +8 -0
  51. data/app/views/authengine/actions/update.html.erb +11 -0
  52. data/app/views/authengine/admin/_show.html.haml +5 -0
  53. data/app/views/authengine/layouts/authengine.html.haml +9 -0
  54. data/app/views/authengine/roles/index.html.haml +12 -0
  55. data/app/views/authengine/roles/new.html.haml +15 -0
  56. data/app/views/authengine/roles/show.html.erb +8 -0
  57. data/app/views/authengine/sessions/new.html.haml +18 -0
  58. data/app/views/authengine/user_mailer/activation.html.erb +5 -0
  59. data/app/views/authengine/user_mailer/forgot_password.html.erb +3 -0
  60. data/app/views/authengine/user_mailer/message_to_admin.html.erb +2 -0
  61. data/app/views/authengine/user_mailer/reset_password.html.erb +1 -0
  62. data/app/views/authengine/user_mailer/signup_notification.html.erb +5 -0
  63. data/app/views/authengine/user_roles/edit.html.haml +10 -0
  64. data/app/views/authengine/user_roles/index.html.haml +14 -0
  65. data/app/views/authengine/user_roles/new.html.haml +8 -0
  66. data/app/views/authengine/useractions/_useraction.html.erb +6 -0
  67. data/app/views/authengine/useractions/index.html.erb +13 -0
  68. data/app/views/authengine/useractions/show.html.haml +14 -0
  69. data/app/views/authengine/useractions/update.html.erb +2 -0
  70. data/app/views/authengine/users/_no_privacy_policy.html.haml +1 -0
  71. data/app/views/authengine/users/_privacy_policy_example.html.haml +36 -0
  72. data/app/views/authengine/users/_user.html.haml +19 -0
  73. data/app/views/authengine/users/edit.html.haml +24 -0
  74. data/app/views/authengine/users/index.html.haml +10 -0
  75. data/app/views/authengine/users/new.html.haml +31 -0
  76. data/app/views/authengine/users/show.html.haml +19 -0
  77. data/app/views/authengine/users/signup.html.haml +52 -0
  78. data/authengine.gemspec +44 -0
  79. data/config/application.rb +1 -0
  80. data/config/routes.rb +43 -0
  81. data/db/migrate/20110320171029_create_authengine_tables.rb +90 -0
  82. data/db/migrate/20110924165900_add_parent_id_to_roles_table.rb +5 -0
  83. data/db/migrate/20110925202800_add_type_field_to_user_roles_table.rb +5 -0
  84. data/db/migrate/20111003074700_add_indexes_to_several_tables.rb +7 -0
  85. data/db/seeds.rb +7 -0
  86. data/lib/application_helper.rb +19 -0
  87. data/lib/authengine.rb +5 -0
  88. data/lib/authengine/engine.rb +44 -0
  89. data/lib/authengine/testing_support/factories/user_factory.rb +13 -0
  90. data/lib/authengine/version.rb +3 -0
  91. data/lib/rails/generators/authengine/authengine_generator.rb +160 -0
  92. data/lib/rails/generators/authengine/templates/initializer.rb +3 -0
  93. data/lib/rails/generators/authengine/templates/migration.rb +16 -0
  94. data/lib/rails/generators/authengine/templates/pre_populate_database.rb +20 -0
  95. data/lib/rails/generators/authengine/templates/schema.rb +69 -0
  96. data/lib/tasks/bootstrap.rake +29 -0
  97. data/spec/authengine_spec.rb +7 -0
  98. data/spec/dummy/.rspec +1 -0
  99. data/spec/dummy/Gemfile +3 -0
  100. data/spec/dummy/Rakefile +8 -0
  101. data/spec/dummy/app/assets/javascripts/jasmine_examples/Player.js +22 -0
  102. data/spec/dummy/app/assets/javascripts/jasmine_examples/Song.js +7 -0
  103. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  104. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  105. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  106. data/spec/dummy/config.ru +4 -0
  107. data/spec/dummy/config/application.rb +50 -0
  108. data/spec/dummy/config/boot.rb +10 -0
  109. data/spec/dummy/config/database.yml +22 -0
  110. data/spec/dummy/config/environment.rb +5 -0
  111. data/spec/dummy/config/environments/development.rb +26 -0
  112. data/spec/dummy/config/environments/production.rb +49 -0
  113. data/spec/dummy/config/environments/test.rb +35 -0
  114. data/spec/dummy/config/initializers/application.rb +1 -0
  115. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  116. data/spec/dummy/config/initializers/inflections.rb +10 -0
  117. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  118. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  119. data/spec/dummy/config/initializers/session_store.rb +8 -0
  120. data/spec/dummy/config/locales/en.yml +5 -0
  121. data/spec/dummy/config/routes.rb +3 -0
  122. data/spec/dummy/db/development.sqlite3 +0 -0
  123. data/spec/dummy/db/schema.rb +87 -0
  124. data/spec/dummy/lib/constants.rb +5 -0
  125. data/spec/dummy/log/development.log +117 -0
  126. data/spec/dummy/log/production.log +0 -0
  127. data/spec/dummy/log/server.log +0 -0
  128. data/spec/dummy/public/404.html +26 -0
  129. data/spec/dummy/public/422.html +26 -0
  130. data/spec/dummy/public/500.html +26 -0
  131. data/spec/dummy/public/favicon.ico +0 -0
  132. data/spec/dummy/public/javascripts/application.js +2 -0
  133. data/spec/dummy/public/javascripts/controls.js +965 -0
  134. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  135. data/spec/dummy/public/javascripts/effects.js +1123 -0
  136. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  137. data/spec/dummy/public/javascripts/rails.js +191 -0
  138. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  139. data/spec/dummy/script/rails +6 -0
  140. data/spec/dummy/spec/javascripts/helpers/.gitkeep +0 -0
  141. data/spec/dummy/spec/javascripts/helpers/SpecHelper.js +9 -0
  142. data/spec/dummy/spec/javascripts/jasmine_examples/PlayerSpec.js +58 -0
  143. data/spec/dummy/spec/javascripts/support/jasmine.yml +76 -0
  144. data/spec/generators/authengine_generator_spec.rb +11 -0
  145. data/spec/integration/navigation_spec.rb +9 -0
  146. data/spec/javascripts/spec.css +3 -0
  147. data/spec/javascripts/spec.js.coffee +2 -0
  148. data/spec/models/action_role_spec.rb +59 -0
  149. data/spec/models/authenticated_system_spec.rb +109 -0
  150. data/spec/models/role_spec.rb +38 -0
  151. data/spec/models/user_factory_spec.rb +7 -0
  152. data/spec/models/user_spec.rb +16 -0
  153. data/spec/requests/sessions_spec.rb +11 -0
  154. data/spec/spec_helper.rb +57 -0
  155. metadata +405 -0
@@ -0,0 +1,191 @@
1
+ (function() {
2
+ // Technique from Juriy Zaytsev
3
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4
+ function isEventSupported(eventName) {
5
+ var el = document.createElement('div');
6
+ eventName = 'on' + eventName;
7
+ var isSupported = (eventName in el);
8
+ if (!isSupported) {
9
+ el.setAttribute(eventName, 'return;');
10
+ isSupported = typeof el[eventName] == 'function';
11
+ }
12
+ el = null;
13
+ return isSupported;
14
+ }
15
+
16
+ function isForm(element) {
17
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18
+ }
19
+
20
+ function isInput(element) {
21
+ if (Object.isElement(element)) {
22
+ var name = element.nodeName.toUpperCase()
23
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24
+ }
25
+ else return false
26
+ }
27
+
28
+ var submitBubbles = isEventSupported('submit'),
29
+ changeBubbles = isEventSupported('change')
30
+
31
+ if (!submitBubbles || !changeBubbles) {
32
+ // augment the Event.Handler class to observe custom events when needed
33
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34
+ function(init, element, eventName, selector, callback) {
35
+ init(element, eventName, selector, callback)
36
+ // is the handler being attached to an element that doesn't support this event?
37
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39
+ // "submit" => "emulated:submit"
40
+ this.eventName = 'emulated:' + this.eventName
41
+ }
42
+ }
43
+ )
44
+ }
45
+
46
+ if (!submitBubbles) {
47
+ // discover forms on the page by observing focus events which always bubble
48
+ document.on('focusin', 'form', function(focusEvent, form) {
49
+ // special handler for the real "submit" event (one-time operation)
50
+ if (!form.retrieve('emulated:submit')) {
51
+ form.on('submit', function(submitEvent) {
52
+ var emulated = form.fire('emulated:submit', submitEvent, true)
53
+ // if custom event received preventDefault, cancel the real one too
54
+ if (emulated.returnValue === false) submitEvent.preventDefault()
55
+ })
56
+ form.store('emulated:submit', true)
57
+ }
58
+ })
59
+ }
60
+
61
+ if (!changeBubbles) {
62
+ // discover form inputs on the page
63
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64
+ // special handler for real "change" events
65
+ if (!input.retrieve('emulated:change')) {
66
+ input.on('change', function(changeEvent) {
67
+ input.fire('emulated:change', changeEvent, true)
68
+ })
69
+ input.store('emulated:change', true)
70
+ }
71
+ })
72
+ }
73
+
74
+ function handleRemote(element) {
75
+ var method, url, params;
76
+
77
+ var event = element.fire("ajax:before");
78
+ if (event.stopped) return false;
79
+
80
+ if (element.tagName.toLowerCase() === 'form') {
81
+ method = element.readAttribute('method') || 'post';
82
+ url = element.readAttribute('action');
83
+ params = element.serialize();
84
+ } else {
85
+ method = element.readAttribute('data-method') || 'get';
86
+ url = element.readAttribute('href');
87
+ params = {};
88
+ }
89
+
90
+ new Ajax.Request(url, {
91
+ method: method,
92
+ parameters: params,
93
+ evalScripts: true,
94
+
95
+ onComplete: function(request) { element.fire("ajax:complete", request); },
96
+ onSuccess: function(request) { element.fire("ajax:success", request); },
97
+ onFailure: function(request) { element.fire("ajax:failure", request); }
98
+ });
99
+
100
+ element.fire("ajax:after");
101
+ }
102
+
103
+ function handleMethod(element) {
104
+ var method = element.readAttribute('data-method'),
105
+ url = element.readAttribute('href'),
106
+ csrf_param = $$('meta[name=csrf-param]')[0],
107
+ csrf_token = $$('meta[name=csrf-token]')[0];
108
+
109
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110
+ element.parentNode.insert(form);
111
+
112
+ if (method !== 'post') {
113
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114
+ form.insert(field);
115
+ }
116
+
117
+ if (csrf_param) {
118
+ var param = csrf_param.readAttribute('content'),
119
+ token = csrf_token.readAttribute('content'),
120
+ field = new Element('input', { type: 'hidden', name: param, value: token });
121
+ form.insert(field);
122
+ }
123
+
124
+ form.submit();
125
+ }
126
+
127
+
128
+ document.on("click", "*[data-confirm]", function(event, element) {
129
+ var message = element.readAttribute('data-confirm');
130
+ if (!confirm(message)) event.stop();
131
+ });
132
+
133
+ document.on("click", "a[data-remote]", function(event, element) {
134
+ if (event.stopped) return;
135
+ handleRemote(element);
136
+ event.stop();
137
+ });
138
+
139
+ document.on("click", "a[data-method]", function(event, element) {
140
+ if (event.stopped) return;
141
+ handleMethod(element);
142
+ event.stop();
143
+ });
144
+
145
+ document.on("submit", function(event) {
146
+ var element = event.findElement(),
147
+ message = element.readAttribute('data-confirm');
148
+ if (message && !confirm(message)) {
149
+ event.stop();
150
+ return false;
151
+ }
152
+
153
+ var inputs = element.select("input[type=submit][data-disable-with]");
154
+ inputs.each(function(input) {
155
+ input.disabled = true;
156
+ input.writeAttribute('data-original-value', input.value);
157
+ input.value = input.readAttribute('data-disable-with');
158
+ });
159
+
160
+ var element = event.findElement("form[data-remote]");
161
+ if (element) {
162
+ handleRemote(element);
163
+ event.stop();
164
+ }
165
+ });
166
+
167
+ document.on("ajax:after", "form", function(event, element) {
168
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169
+ inputs.each(function(input) {
170
+ input.value = input.readAttribute('data-original-value');
171
+ input.removeAttribute('data-original-value');
172
+ input.disabled = false;
173
+ });
174
+ });
175
+
176
+ Ajax.Responders.register({
177
+ onCreate: function(request) {
178
+ var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
179
+
180
+ if (csrf_meta_tag) {
181
+ var header = 'X-CSRF-Token',
182
+ token = csrf_meta_tag.readAttribute('content');
183
+
184
+ if (!request.options.requestHeaders) {
185
+ request.options.requestHeaders = {};
186
+ }
187
+ request.options.requestHeaders[header] = token;
188
+ }
189
+ }
190
+ });
191
+ })();
File without changes
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,9 @@
1
+ beforeEach(function() {
2
+ this.addMatchers({
3
+ toBePlaying: function(expectedSong) {
4
+ var player = this.actual;
5
+ return player.currentlyPlayingSong === expectedSong
6
+ && player.isPlaying;
7
+ }
8
+ })
9
+ });
@@ -0,0 +1,58 @@
1
+ describe("Player", function() {
2
+ var player;
3
+ var song;
4
+
5
+ beforeEach(function() {
6
+ player = new Player();
7
+ song = new Song();
8
+ });
9
+
10
+ it("should be able to play a Song", function() {
11
+ player.play(song);
12
+ expect(player.currentlyPlayingSong).toEqual(song);
13
+
14
+ //demonstrates use of custom matcher
15
+ expect(player).toBePlaying(song);
16
+ });
17
+
18
+ describe("when song has been paused", function() {
19
+ beforeEach(function() {
20
+ player.play(song);
21
+ player.pause();
22
+ });
23
+
24
+ it("should indicate that the song is currently paused", function() {
25
+ expect(player.isPlaying).toBeFalsy();
26
+
27
+ // demonstrates use of 'not' with a custom matcher
28
+ expect(player).not.toBePlaying(song);
29
+ });
30
+
31
+ it("should be possible to resume", function() {
32
+ player.resume();
33
+ expect(player.isPlaying).toBeTruthy();
34
+ expect(player.currentlyPlayingSong).toEqual(song);
35
+ });
36
+ });
37
+
38
+ // demonstrates use of spies to intercept and test method calls
39
+ it("tells the current song if the user has made it a favorite", function() {
40
+ spyOn(song, 'persistFavoriteStatus');
41
+
42
+ player.play(song);
43
+ player.makeFavorite();
44
+
45
+ expect(song.persistFavoriteStatus).toHaveBeenCalledWith(true);
46
+ });
47
+
48
+ //demonstrates use of expected exceptions
49
+ describe("#resume", function() {
50
+ it("should throw an exception if song is already playing", function() {
51
+ player.play(song);
52
+
53
+ expect(function() {
54
+ player.resume();
55
+ }).toThrow("song is already playing");
56
+ });
57
+ });
58
+ });
@@ -0,0 +1,76 @@
1
+ # src_files
2
+ #
3
+ # Return an array of filepaths relative to src_dir to include before jasmine specs.
4
+ # Default: []
5
+ #
6
+ # EXAMPLE:
7
+ #
8
+ # src_files:
9
+ # - lib/source1.js
10
+ # - lib/source2.js
11
+ # - dist/**/*.js
12
+ #
13
+ src_files:
14
+ - assets/application.js
15
+
16
+ # stylesheets
17
+ #
18
+ # Return an array of stylesheet filepaths relative to src_dir to include before jasmine specs.
19
+ # Default: []
20
+ #
21
+ # EXAMPLE:
22
+ #
23
+ # stylesheets:
24
+ # - css/style.css
25
+ # - stylesheets/*.css
26
+ #
27
+ stylesheets:
28
+ - stylesheets/**/*.css
29
+
30
+ # helpers
31
+ #
32
+ # Return an array of filepaths relative to spec_dir to include before jasmine specs.
33
+ # Default: ["helpers/**/*.js"]
34
+ #
35
+ # EXAMPLE:
36
+ #
37
+ # helpers:
38
+ # - helpers/**/*.js
39
+ #
40
+ helpers:
41
+ - helpers/**/*.js
42
+
43
+ # spec_files
44
+ #
45
+ # Return an array of filepaths relative to spec_dir to include.
46
+ # Default: ["**/*[sS]pec.js"]
47
+ #
48
+ # EXAMPLE:
49
+ #
50
+ # spec_files:
51
+ # - **/*[sS]pec.js
52
+ #
53
+ spec_files:
54
+ - '**/*[sS]pec.js'
55
+
56
+ # src_dir
57
+ #
58
+ # Source directory path. Your src_files must be returned relative to this path. Will use root if left blank.
59
+ # Default: project root
60
+ #
61
+ # EXAMPLE:
62
+ #
63
+ # src_dir: public
64
+ #
65
+ src_dir:
66
+
67
+ # spec_dir
68
+ #
69
+ # Spec directory path. Your spec_files must be returned relative to this path.
70
+ # Default: spec/javascripts
71
+ #
72
+ # EXAMPLE:
73
+ #
74
+ # spec_dir: spec/javascripts
75
+ #
76
+ spec_dir: spec/javascripts
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ # just a placeholder
3
+ describe "authengine spec generator" do
4
+ before(:all) do
5
+ #@ag = AuthengineGenerator.new
6
+ end
7
+
8
+ it "should do something" do
9
+ #@ag.copy_initializer_file.should be_true
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Navigation" do
4
+ include Capybara::DSL
5
+
6
+ it "should be a valid app" do
7
+ ::Rails.application.should be_a(Dummy::Application)
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require application
3
+ */
@@ -0,0 +1,2 @@
1
+ #= require application
2
+ #= require_tree .
@@ -0,0 +1,59 @@
1
+ require File.expand_path("../../spec_helper", __FILE__)
2
+
3
+
4
+ describe 'permits_access_for class method' do
5
+ before(:each) do
6
+ @role = Role.create(:name => 'chief')
7
+ @controller = Controller.create(:controller_name => 'traveller')
8
+ @action = Action.create(:action_name => 'travel', :controller_id => @controller.id)
9
+ @user = FactoryGirl.create(:user, :login => 'just_me')
10
+ @user_role = UserRole.create(:role_id => @role.id, :user_id => @user.id)
11
+ @action_role = ActionRole.create(:action_id => @action.id, :role_id => @role.id)
12
+ end
13
+
14
+ it "action is permitted for user's role" do
15
+ ActionRole.permits_access_for(@controller.controller_name, @action.action_name, @user.roles(true).map(&:id)).should == true
16
+ end
17
+
18
+ it "action is not permitted for user's role" do
19
+ ActionRole.permits_access_for(@controller.controller_name, 'some_action', @user.roles(true).map(&:id)).should == false
20
+ end
21
+
22
+ it "different user tries to access the action" do
23
+ @user = FactoryGirl.create(:user, :login => 'another_person')
24
+ ActionRole.permits_access_for(@controller.controller_name, @action.action_name, @user.roles.map(&:id)).should == false
25
+ end
26
+
27
+ it "user has a role that does not permit access to the requested action" do
28
+ UserRole.delete_all
29
+ @user_role = UserRole.create(:role_id => 555, :user_id => @user.id)
30
+ ActionRole.permits_access_for(@controller.controller_name, @action.action_name, @user.user_roles.map(&:role_id)).should == false
31
+ end
32
+
33
+ it "user's role does not permit access to the requested action" do
34
+ ActionRole.delete_all
35
+ @action_role = ActionRole.create(:action_id => @action.id, :role_id => 555)
36
+ ActionRole.permits_access_for(@controller.controller_name, @action.action_name, @user.roles(true).map(&:id)).should == false
37
+ end
38
+ end
39
+
40
+ describe "permits_access_for class method" do
41
+ before(:each) do
42
+ @role = Role.create(:name => 'chief')
43
+ @another_role = Role.create(:name => 'minion')
44
+ @controller = Controller.create(:controller_name => 'traveller')
45
+ @action = Action.create(:action_name => 'travel', :controller_id => @controller.id)
46
+ @user = FactoryGirl.create(:user, :login => 'just_me')
47
+ @action_role = ActionRole.create(:action_id => @action.id, :role_id => @role.id)
48
+ end
49
+
50
+ it "should permit when one of the passed-in roles has an action_role that links to the passed in controller/action" do
51
+ role_ids = [@role.id]
52
+ ActionRole.permits_access_for(@controller.controller_name, @action.action_name, role_ids).should == true
53
+ end
54
+
55
+ it "should not permit when none of the passed-in roles has an action role for the passed-in controller/action" do
56
+ role_ids = [@another_role.id]
57
+ ActionRole.permits_access_for(@controller.controller_name, @action.action_name, role_ids).should == false
58
+ end
59
+ end
@@ -0,0 +1,109 @@
1
+ require Authengine::Engine.root.join('app', 'models', 'authenticated_system').to_s
2
+ require Authengine::Engine.root.join('app', 'models', 'authorized_system').to_s
3
+ require 'flexmock'
4
+ SITE_URL = "same_domain.com"
5
+
6
+ RSpec.configure do |config|
7
+ config.mock_with :flexmock
8
+ end
9
+
10
+
11
+ class Foobar
12
+ attr_accessor :flash
13
+
14
+ def initialize
15
+ @flash = {}
16
+ end
17
+
18
+ def extension; end
19
+
20
+ def headers
21
+ {}
22
+ end
23
+
24
+
25
+ def render(something); end
26
+
27
+ include AuthenticatedSystem
28
+ include AuthorizedSystem
29
+ end
30
+
31
+ describe "AuthenticatedSystem redirection when permission is denied" do
32
+
33
+ it "redirects to the login page when user came from another site" do
34
+ ext = flexmock('extension')
35
+ ext.should_receive(:html).once.and_yield
36
+ ext.should_receive(:xml).once.and_yield
37
+ flexmock(Foobar).new_instances do |f|
38
+ f.should_receive(:respond_to).once.and_yield(ext)
39
+ f.should_receive(:session).and_return({:refer_to => nil})
40
+ env = flexmock("env",
41
+ :env => {"HTTP_REFERER" => "http://same_domain.com/some_page"},
42
+ :fullpath => "http://same_domain.com/some_page")
43
+ f.should_receive(:request).and_return(env)
44
+ f.should_receive(:root_path).and_return("root_path")
45
+ f.should_receive(:domain_name).and_return("http://same_domain.com/some_page")
46
+ f.should_receive("redirect_to").once.with("root_path")
47
+ end
48
+
49
+ Foobar.new.send('permission_denied')
50
+ end
51
+
52
+ it "redirects to the login page if the http referer is not present" do
53
+ ext = flexmock('extension')
54
+ ext.should_receive(:html).once.and_yield
55
+ ext.should_receive(:xml).once.and_yield
56
+ flexmock(Foobar).new_instances do |f|
57
+ f.should_receive(:respond_to).once.and_yield(ext)
58
+ f.should_receive(:session).and_return({:refer_to => nil})
59
+ env = flexmock("env",
60
+ :env => {"HTTP_REFERER" => nil},
61
+ :fullpath => "http://same_domain.com/some_page")
62
+ f.should_receive(:request).and_return(env)
63
+ f.should_receive(:root_path).and_return("root_path")
64
+ f.should_receive(:domain_name).and_return("http://same_domain.com/some_page")
65
+ f.should_receive("redirect_to").once.with("root_path")
66
+ end
67
+
68
+ Foobar.new.send('permission_denied')
69
+ end
70
+
71
+ context "when user came from this site" do
72
+ it "redirects to the previous page if it's not the same as the requested page" do
73
+ ext = flexmock('extension')
74
+ ext.should_receive(:html).once.and_yield
75
+ ext.should_receive(:xml).once.and_yield
76
+ flexmock(Foobar).new_instances do |f|
77
+ f.should_receive(:respond_to).once.and_yield(ext)
78
+ f.should_receive(:session).and_return({:refer_to => nil})
79
+ env = flexmock("env",
80
+ :env => {"HTTP_REFERER" => "http://same_domain.com/different_page"},
81
+ :fullpath => "http://same_domain.com/some_page")
82
+ f.should_receive(:request).and_return(env)
83
+ f.should_receive(:root_path).and_return("root_path")
84
+ f.should_receive(:domain_name).and_return("http://same_domain.com/some_page")
85
+ f.should_receive("redirect_to").once.with("http://same_domain.com/different_page")
86
+ end
87
+
88
+ Foobar.new.send('permission_denied')
89
+ end
90
+
91
+ it "redirects to the login page if the previous page is the same as the requested page" do
92
+ ext = flexmock('extension')
93
+ ext.should_receive(:html).once.and_yield
94
+ ext.should_receive(:xml).once.and_yield
95
+ flexmock(Foobar).new_instances do |f|
96
+ f.should_receive(:respond_to).once.and_yield(ext)
97
+ f.should_receive(:session).and_return({:refer_to => nil})
98
+ env = flexmock("env",
99
+ :env => {"HTTP_REFERER" => "http://same_domain.com/some_page"},
100
+ :fullpath => "http://same_domain.com/some_page")
101
+ f.should_receive(:request).and_return(env)
102
+ f.should_receive(:root_path).and_return("root_path")
103
+ f.should_receive("redirect_to").once.with("root_path")
104
+ end
105
+
106
+ Foobar.new.send('permission_denied')
107
+ end
108
+ end
109
+ end