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.
- data/.gitignore +10 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/README.md +86 -0
- data/Rakefile +31 -0
- data/app/assets/images/message_block/back.gif +0 -0
- data/app/assets/images/message_block/back_m.gif +0 -0
- data/app/assets/images/message_block/confirmation.gif +0 -0
- data/app/assets/images/message_block/confirmation_m.gif +0 -0
- data/app/assets/images/message_block/error.gif +0 -0
- data/app/assets/images/message_block/error_m.gif +0 -0
- data/app/assets/images/message_block/info.gif +0 -0
- data/app/assets/images/message_block/info_m.gif +0 -0
- data/app/assets/images/message_block/notice.gif +0 -0
- data/app/assets/images/message_block/notice_m.gif +0 -0
- data/app/assets/images/message_block/warn.gif +0 -0
- data/app/assets/images/message_block/warn_m.gif +0 -0
- data/app/assets/stylesheets/authengine.css +3 -0
- data/app/assets/stylesheets/message_block.css +45 -0
- data/app/controllers/authengine/accounts_controller.rb +56 -0
- data/app/controllers/authengine/action_roles_controller.rb +22 -0
- data/app/controllers/authengine/actions_controller.rb +17 -0
- data/app/controllers/authengine/roles_controller.rb +35 -0
- data/app/controllers/authengine/sessions_controller.rb +75 -0
- data/app/controllers/authengine/user_roles_controller.rb +55 -0
- data/app/controllers/authengine/useractions_controller.rb +17 -0
- data/app/controllers/authengine/users_controller.rb +137 -0
- data/app/helpers/application_helper.rb +2 -0
- data/app/helpers/authengine/users_helper.rb +11 -0
- data/app/helpers/roles_helper.rb +2 -0
- data/app/mailers/authengine/user_mailer.rb +53 -0
- data/app/models/action.rb +54 -0
- data/app/models/action_role.rb +29 -0
- data/app/models/authenticated_system.rb +179 -0
- data/app/models/authorized_system.rb +41 -0
- data/app/models/controller.rb +124 -0
- data/app/models/role.rb +71 -0
- data/app/models/session.rb +3 -0
- data/app/models/session_role.rb +17 -0
- data/app/models/user.rb +191 -0
- data/app/models/user_observer.rb +14 -0
- data/app/models/user_role.rb +4 -0
- data/app/models/useraction.rb +56 -0
- data/app/views/authengine/accounts/edit.html.erb +19 -0
- data/app/views/authengine/actions/create.html.erb +2 -0
- data/app/views/authengine/actions/destroy.html.erb +2 -0
- data/app/views/authengine/actions/edit.html.erb +80 -0
- data/app/views/authengine/actions/index.html.haml +26 -0
- data/app/views/authengine/actions/new.html.erb +2 -0
- data/app/views/authengine/actions/show.html.erb +8 -0
- data/app/views/authengine/actions/update.html.erb +11 -0
- data/app/views/authengine/admin/_show.html.haml +5 -0
- data/app/views/authengine/layouts/authengine.html.haml +9 -0
- data/app/views/authengine/roles/index.html.haml +12 -0
- data/app/views/authengine/roles/new.html.haml +15 -0
- data/app/views/authengine/roles/show.html.erb +8 -0
- data/app/views/authengine/sessions/new.html.haml +18 -0
- data/app/views/authengine/user_mailer/activation.html.erb +5 -0
- data/app/views/authengine/user_mailer/forgot_password.html.erb +3 -0
- data/app/views/authengine/user_mailer/message_to_admin.html.erb +2 -0
- data/app/views/authengine/user_mailer/reset_password.html.erb +1 -0
- data/app/views/authengine/user_mailer/signup_notification.html.erb +5 -0
- data/app/views/authengine/user_roles/edit.html.haml +10 -0
- data/app/views/authengine/user_roles/index.html.haml +14 -0
- data/app/views/authengine/user_roles/new.html.haml +8 -0
- data/app/views/authengine/useractions/_useraction.html.erb +6 -0
- data/app/views/authengine/useractions/index.html.erb +13 -0
- data/app/views/authengine/useractions/show.html.haml +14 -0
- data/app/views/authengine/useractions/update.html.erb +2 -0
- data/app/views/authengine/users/_no_privacy_policy.html.haml +1 -0
- data/app/views/authengine/users/_privacy_policy_example.html.haml +36 -0
- data/app/views/authengine/users/_user.html.haml +19 -0
- data/app/views/authengine/users/edit.html.haml +24 -0
- data/app/views/authengine/users/index.html.haml +10 -0
- data/app/views/authengine/users/new.html.haml +31 -0
- data/app/views/authengine/users/show.html.haml +19 -0
- data/app/views/authengine/users/signup.html.haml +52 -0
- data/authengine.gemspec +44 -0
- data/config/application.rb +1 -0
- data/config/routes.rb +43 -0
- data/db/migrate/20110320171029_create_authengine_tables.rb +90 -0
- data/db/migrate/20110924165900_add_parent_id_to_roles_table.rb +5 -0
- data/db/migrate/20110925202800_add_type_field_to_user_roles_table.rb +5 -0
- data/db/migrate/20111003074700_add_indexes_to_several_tables.rb +7 -0
- data/db/seeds.rb +7 -0
- data/lib/application_helper.rb +19 -0
- data/lib/authengine.rb +5 -0
- data/lib/authengine/engine.rb +44 -0
- data/lib/authengine/testing_support/factories/user_factory.rb +13 -0
- data/lib/authengine/version.rb +3 -0
- data/lib/rails/generators/authengine/authengine_generator.rb +160 -0
- data/lib/rails/generators/authengine/templates/initializer.rb +3 -0
- data/lib/rails/generators/authengine/templates/migration.rb +16 -0
- data/lib/rails/generators/authengine/templates/pre_populate_database.rb +20 -0
- data/lib/rails/generators/authengine/templates/schema.rb +69 -0
- data/lib/tasks/bootstrap.rake +29 -0
- data/spec/authengine_spec.rb +7 -0
- data/spec/dummy/.rspec +1 -0
- data/spec/dummy/Gemfile +3 -0
- data/spec/dummy/Rakefile +8 -0
- data/spec/dummy/app/assets/javascripts/jasmine_examples/Player.js +22 -0
- data/spec/dummy/app/assets/javascripts/jasmine_examples/Song.js +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +50 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/application.rb +1 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +87 -0
- data/spec/dummy/lib/constants.rb +5 -0
- data/spec/dummy/log/development.log +117 -0
- data/spec/dummy/log/production.log +0 -0
- data/spec/dummy/log/server.log +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +191 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/dummy/spec/javascripts/helpers/.gitkeep +0 -0
- data/spec/dummy/spec/javascripts/helpers/SpecHelper.js +9 -0
- data/spec/dummy/spec/javascripts/jasmine_examples/PlayerSpec.js +58 -0
- data/spec/dummy/spec/javascripts/support/jasmine.yml +76 -0
- data/spec/generators/authengine_generator_spec.rb +11 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/javascripts/spec.css +3 -0
- data/spec/javascripts/spec.js.coffee +2 -0
- data/spec/models/action_role_spec.rb +59 -0
- data/spec/models/authenticated_system_spec.rb +109 -0
- data/spec/models/role_spec.rb +38 -0
- data/spec/models/user_factory_spec.rb +7 -0
- data/spec/models/user_spec.rb +16 -0
- data/spec/requests/sessions_spec.rb +11 -0
- data/spec/spec_helper.rb +57 -0
- 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'
|
|
File without changes
|
|
@@ -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,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
|