ucb_rails_security 2.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/CHANGELOG +6 -0
  2. data/Manifest +56 -0
  3. data/README +195 -0
  4. data/Rakefile +21 -0
  5. data/TODO +3 -0
  6. data/generators/ucb_rails_security/templates/controllers/ucb_security/base_controller.rb +17 -0
  7. data/generators/ucb_rails_security/templates/controllers/ucb_security/ldap_search_controller.rb +10 -0
  8. data/generators/ucb_rails_security/templates/controllers/ucb_security/role_users_controller.rb +27 -0
  9. data/generators/ucb_rails_security/templates/controllers/ucb_security/roles_controller.rb +52 -0
  10. data/generators/ucb_rails_security/templates/controllers/ucb_security/user_roles_controller.rb +29 -0
  11. data/generators/ucb_rails_security/templates/controllers/ucb_security/users_controller.rb +59 -0
  12. data/generators/ucb_rails_security/templates/db/migrate/xxx_create_ucb_rails_security_tables.rb +31 -0
  13. data/generators/ucb_rails_security/templates/helpers/ucb_security/base_helper.rb +23 -0
  14. data/generators/ucb_rails_security/templates/helpers/ucb_security/builder.rb +25 -0
  15. data/generators/ucb_rails_security/templates/helpers/ucb_security/roles_helper.rb +2 -0
  16. data/generators/ucb_rails_security/templates/helpers/ucb_security/users_helper.rb +2 -0
  17. data/generators/ucb_rails_security/templates/initializers/ucb_security_config.rb +20 -0
  18. data/generators/ucb_rails_security/templates/javascripts/ucb_security.js +99 -0
  19. data/generators/ucb_rails_security/templates/models/ldap_search.rb +48 -0
  20. data/generators/ucb_rails_security/templates/models/role.rb +32 -0
  21. data/generators/ucb_rails_security/templates/models/user.rb +106 -0
  22. data/generators/ucb_rails_security/templates/models/user_roles.rb +3 -0
  23. data/generators/ucb_rails_security/templates/stylesheets/ucb_security.css +347 -0
  24. data/generators/ucb_rails_security/templates/views/layouts/ucb_security/_main_navigation.html.erb +10 -0
  25. data/generators/ucb_rails_security/templates/views/layouts/ucb_security/application.html.erb +24 -0
  26. data/generators/ucb_rails_security/templates/views/ucb_security/ldap_search/index.html.erb +62 -0
  27. data/generators/ucb_rails_security/templates/views/ucb_security/role_users/_new.html.erb +11 -0
  28. data/generators/ucb_rails_security/templates/views/ucb_security/role_users/edit.html.erb +37 -0
  29. data/generators/ucb_rails_security/templates/views/ucb_security/roles/_users.html.erb +14 -0
  30. data/generators/ucb_rails_security/templates/views/ucb_security/roles/edit.html.erb +19 -0
  31. data/generators/ucb_rails_security/templates/views/ucb_security/roles/index.html.erb +34 -0
  32. data/generators/ucb_rails_security/templates/views/ucb_security/roles/new.html.erb +19 -0
  33. data/generators/ucb_rails_security/templates/views/ucb_security/roles/show.html.erb +27 -0
  34. data/generators/ucb_rails_security/templates/views/ucb_security/user_roles/edit.html.erb +17 -0
  35. data/generators/ucb_rails_security/templates/views/ucb_security/users/edit.html.erb +23 -0
  36. data/generators/ucb_rails_security/templates/views/ucb_security/users/index.html.erb +43 -0
  37. data/generators/ucb_rails_security/templates/views/ucb_security/users/new.html.erb +29 -0
  38. data/generators/ucb_rails_security/templates/views/ucb_security/users/show.html.erb +43 -0
  39. data/generators/ucb_rails_security/ucb_rails_security_generator.rb +191 -0
  40. data/init.rb +9 -0
  41. data/lib/helpers/rspec_helpers.rb +119 -0
  42. data/lib/tasks/ucb_rails_security.rake +22 -0
  43. data/lib/ucb_rails_security.rb +60 -0
  44. data/lib/ucb_rails_security_casauthentication.rb +117 -0
  45. data/lib/ucb_rails_security_logger.rb +33 -0
  46. data/lib/ucb_rs_controller_methods.rb +496 -0
  47. data/rdoc_includes/application_controller_rb.txt +9 -0
  48. data/rspec/_all_specs.rb +5 -0
  49. data/rspec/_setup.rb +36 -0
  50. data/rspec/filter_ldap_spec.rb +87 -0
  51. data/rspec/filter_role_spec.rb +56 -0
  52. data/rspec/filter_spec.rb +37 -0
  53. data/rspec/filter_user_spec.rb +55 -0
  54. data/rspec/logged_in_status_spec.rb +226 -0
  55. data/rspec/ucb_rails_security_casauthentication_spec.rb +83 -0
  56. data/rspec/ucb_rails_security_spec.rb +34 -0
  57. data/test/test_rails-2.0.x/test/test_helper.rb +38 -0
  58. data/test/test_rails-2.1.x/test/test_helper.rb +38 -0
  59. data/ucb_rails_security.gemspec +41 -0
  60. metadata +147 -0
@@ -0,0 +1,99 @@
1
+
2
+ var DoubleSelectList = {
3
+ /* Takes the dom Ids of two Select Elements. Moves the
4
+ * options from the Element with fromId that are selected
5
+ * to the Element with toId
6
+ */
7
+ moveSelected: function(fromId, toId) {
8
+ var fromList = $(fromId)
9
+ var toList = $(toId)
10
+
11
+ if (!fromList) {
12
+ throw new Error("Dom id for fromId not found: " + fromId)
13
+ } else if (!toList) {
14
+ throw new Error("Dom id for toId not found: " + toId)
15
+ }
16
+
17
+ this._transferSelected(fromList, toList);
18
+ },
19
+ /* Takes the dom Ids of two Select Elements. Moves all the
20
+ * options from the Element with fromId to the Element
21
+ * with toId
22
+ */
23
+ moveAll: function(fromId, toId) {
24
+ var fromList = $(fromId)
25
+ var toList = $(toId)
26
+
27
+ if (!fromList) {
28
+ throw new Error("Dom id for fromId not found: " + fromId)
29
+ } else if (!toList) {
30
+ throw new Error("Dom id for toId not found: " + toId)
31
+ }
32
+
33
+ this._transferAll(fromList, toList);
34
+ },
35
+ /*
36
+ * Takes an array of Option elements and sets their selected attribute to true/false.
37
+ *
38
+ * setSelectedToFalse([<option selected=true></option>], false)
39
+ * => [<option selected=false></option>]
40
+ */
41
+ setOptionsSelectedAttribute: function(selectOptions, selectedValue) {
42
+ return selectOptions.map(
43
+ function(elem) {
44
+ elem.selected = selectedValue;
45
+ return elem;
46
+ }
47
+ );
48
+
49
+ },
50
+ /**
51
+ * When the form is submitted, we want to make sure the values from both
52
+ * select lists are sent to our controller/action. Only select options
53
+ * that have their selected attribute set to true actually get submitted.
54
+ * We call this function the first time the page loads and as soon as the
55
+ * submit button is clicked, it updates the selected attribute of both
56
+ * select lists to true
57
+ */
58
+ initSubmitCallback: function(buttonId, fromId, toId) {
59
+ var fromOptions = $(fromId).childElements();
60
+ var toOptions = $(toId).childElements();
61
+ $(buttonId).observe('click', function() { fromOptions.each(function(elem) {elem.selected = true}) })
62
+ $(buttonId).observe('click', function() { toOptions.each(function(elem) {elem.selected = true}) })
63
+ },
64
+
65
+
66
+ /************************************************************************
67
+ * Private Methods
68
+ ************************************************************************/
69
+
70
+ _transferAll: function(fromList, toList) {
71
+ var fromOptions = fromList.childElements();
72
+ var toOptions = toList.childElements();
73
+ var newOptions = new Array(fromOptions, toOptions).flatten();
74
+
75
+ newOptions = newOptions.sort(this._optionsSorter);
76
+ newOptions = this.setOptionsSelectedAttribute(newOptions, false);
77
+ toOptions.each( function(elem) { elem.remove(); } );
78
+ newOptions.each( function(elem) { toList.insert(elem); } );
79
+ },
80
+ _transferSelected: function(fromList, toList) {
81
+ var selFromOptions = fromList.childElements().select(
82
+ function(elem) { return elem.selected }
83
+ );
84
+ selFromOptions = this.setOptionsSelectedAttribute(selFromOptions, false);
85
+
86
+ var toOptions = toList.childElements();
87
+ var newOptions = new Array(selFromOptions, toOptions).flatten();
88
+ newOptions = newOptions.sort(this._optionsSorter);
89
+ newOptions.each( function(elem) { toList.insert(elem) } );
90
+ },
91
+ /*
92
+ * To be used as a comparison function with Array.sort. Compares the
93
+ * the text of two Option elements and sorts them Alpha ASC.
94
+ */
95
+ _optionsSorter: function(option1, option2) {
96
+ return option1.text > option2.text ? 1 : (option1.text < option2.text ? -1 : 0);
97
+ },
98
+
99
+ };
@@ -0,0 +1,48 @@
1
+ require 'ucb_ldap'
2
+
3
+ class LdapSearch
4
+ SEARCH_TERMS = [
5
+ [:last_name_and_first_name, 'Last Name, First Name'],
6
+ [:last_name, 'Last Name'],
7
+ [:first_name, 'First Name'],
8
+ [:email, 'Email'],
9
+ [:phone, 'Phone'],
10
+ [:department, 'Department'],
11
+ [:ldap_uid, 'UID']
12
+ ]
13
+
14
+ LDAP_ALIASES = {
15
+ :first_name => :givenname,
16
+ :last_name => :sn,
17
+ :email => :mail,
18
+ :phone => :telephonenumber,
19
+ :department => :berkeleyeduunitcalnetdeptname,
20
+ :ldap_uid => :uid,
21
+ }
22
+
23
+ def self.search_term_select_list
24
+ SEARCH_TERMS.collect { |item| [item[1], item[0]] }
25
+ end
26
+
27
+ def self.search_arguments_blank?(search_term, search_value)
28
+ search_term.nil? || search_term.empty? || search_value.nil? || search_value.empty?
29
+ end
30
+
31
+ def self.find(search_term, search_value)
32
+ return [] if search_arguments_blank?(search_term, search_value)
33
+
34
+ search_hash = {}
35
+ if search_term.to_sym == SEARCH_TERMS[0][0]
36
+ lname_value, fname_value = search_value.split(",").map { |v| v.strip }
37
+ lname, fname = search_term.split("_and_")
38
+ return [] if lname.nil? || fname.nil?
39
+ search_hash[LDAP_ALIASES[fname.to_sym]] = "#{fname_value}"
40
+ search_hash[LDAP_ALIASES[lname.to_sym]] = "#{lname_value}"
41
+ else
42
+ search_hash[LDAP_ALIASES[search_term.to_sym]] = "#{search_value}"
43
+ end
44
+
45
+ UCB::LDAP::Person.search(:filter => search_hash)
46
+ end
47
+
48
+ end
@@ -0,0 +1,32 @@
1
+ class Role < ActiveRecord::Base
2
+ has_and_belongs_to_many(:users, :join_table => "user_roles", :order => 'last_name')
3
+
4
+ validates_presence_of :name
5
+ validates_uniqueness_of :name
6
+
7
+
8
+ def formatted_created_at()
9
+ created_at.strftime('%m-%d-%Y')
10
+ end
11
+
12
+ def formatted_updated_at()
13
+ updated_at.strftime('%m-%d-%Y')
14
+ end
15
+
16
+ def users_menu_list()
17
+ self.users.map { |u| [u.display_name, u.id] }
18
+ end
19
+
20
+ def non_users_menu_list
21
+ self.non_users.map { |u| [u.display_name, u.id] }
22
+ end
23
+
24
+ def non_users
25
+ sql = %(
26
+ SELECT users.* FROM users LEFT JOIN user_roles
27
+ ON (users.id = user_roles.user_id AND user_roles.role_id = #{id})
28
+ WHERE user_roles.role_id IS NULL
29
+ )
30
+ User.find_by_sql(sql)
31
+ end
32
+ end
@@ -0,0 +1,106 @@
1
+ class User < ActiveRecord::Base
2
+ has_and_belongs_to_many :roles, :join_table => 'user_roles', :order => 'name'
3
+
4
+ validates_uniqueness_of :ldap_uid
5
+ validates_uniqueness_of :email, :unless => lambda { |user| user.email.blank? }
6
+ validates_presence_of :ldap_uid, :first_name, :last_name
7
+
8
+ def formatted_created_at()
9
+ created_at.strftime('%m-%d-%Y')
10
+ end
11
+
12
+ def current_user?(ldap_uid)
13
+ self.ldap_uid == ldap_uid
14
+ end
15
+
16
+ def full_name()
17
+ "#{first_name} #{last_name}"
18
+ end
19
+
20
+ def display_name()
21
+ "#{last_name}, #{first_name}"
22
+ end
23
+
24
+ def sync_attributes_with_ldap!()
25
+ ldap_person = UCB::LDAP::Person.find_by_uid(self.ldap_uid)
26
+ raise UCB::LDAP::Person::RecordNotFound if ldap_person.nil?
27
+ self.update_attributes!(self.class.attributes_hash_for_ldap_person(ldap_person))
28
+ end
29
+
30
+ class << self
31
+ ### Start Class Aliases ###
32
+ #
33
+ # These methods provide aliases for ActiveRecord's
34
+ # dynamic finders and can't be aliased with the
35
+ # usual: alias :new_method :old_method
36
+ #
37
+ def find_by_uid(ldap_uid)
38
+ find_by_ldap_uid(ldap_uid)
39
+ end
40
+
41
+ def new_from_uid(ldap_uid)
42
+ new_from_ldap_uid(ldap_uid)
43
+ end
44
+ ### End Class Aliases ####
45
+
46
+ def find_or_create_by_ldap_uid!(ldap_uid)
47
+ user = find_or_create_by_ldap_uid(ldap_uid)
48
+ if user.new_record?
49
+ ldap_person = UCB::LDAP::Person.find_by_uid(ldap_uid)
50
+ raise UCB::LDAP::Person::RecordNotFound if ldap_person.nil?
51
+ user.attributes = attributes_hash_for_ldap_person(ldap_person)
52
+ user.save!
53
+ end
54
+ user
55
+ end
56
+
57
+ def new_from_ldap_uid(ldap_uid)
58
+ ldap_person = ldap_uid.nil? ? nil : UCB::LDAP::Person.find_by_uid(ldap_uid)
59
+ if ldap_person.nil?
60
+ self.new
61
+ else
62
+ user = self.new
63
+ user.attributes = attributes_hash_for_ldap_person(ldap_person)
64
+ user
65
+ end
66
+ end
67
+
68
+ def attributes_hash_for_ldap_person(ldap_person)
69
+ {
70
+ :ldap_uid => ldap_person.uid,
71
+ :first_name => ldap_person.first_name,
72
+ :last_name => ldap_person.last_name,
73
+ :phone => ldap_person.phone,
74
+ :email => ldap_person.email,
75
+ :department => ldap_person.dept_name
76
+ }
77
+ end
78
+
79
+ def find_in_ldap(search_params = {})
80
+ return [] if search_params.empty?
81
+
82
+ ldap_people = []
83
+ UCB::LDAP::Person.search(:filter => search_params).each do |person|
84
+ ldap_people << person
85
+ end
86
+ ldap_people
87
+ end
88
+
89
+ def sync_all_with_ldap!()
90
+ unfound = []
91
+ users = self.find(:all).each do |u|
92
+ begin
93
+ u.sync_attributes_with_ldap!
94
+ rescue UCB::LDAP::Person::RecordNotFound => e
95
+ unfound << u.uid
96
+ end
97
+ end
98
+
99
+ unless unfound.blank?
100
+ msg = "Sync failed for uids: #{unfound.join(',')}"
101
+ raise(UCB::LDAP::Person::RecordNotFound, msg)
102
+ end
103
+ end
104
+ end
105
+
106
+ end
@@ -0,0 +1,3 @@
1
+ class UserRole < ActiveRecord::Base
2
+ set_table_name("user_roles")
3
+ end
@@ -0,0 +1,347 @@
1
+ #container {
2
+ width: 100%;
3
+ background-color: #fff;
4
+ color: #333;
5
+ line-height: 160%;
6
+ vertical-align: top;
7
+ }
8
+
9
+ #main {
10
+ padding: 1.5em;
11
+ overflow: clip;
12
+ vertical-align: top;
13
+ }
14
+
15
+ #site_header {
16
+ color: #02305c;
17
+ font-weight: bold;
18
+ font-size: 1.8em;
19
+ padding: .5em;
20
+ background-color: #fff;
21
+ }
22
+
23
+ #site_header div {
24
+ font-size: .4em;
25
+ float: right;
26
+ }
27
+
28
+ #site_header div strong {
29
+ color: black;
30
+ font-style: oblique;
31
+ }
32
+ /* Start General Element Styles */
33
+ html {
34
+ padding: 0em;
35
+ }
36
+
37
+ body {
38
+ margin: 0em;
39
+ background-color: white;
40
+ }
41
+
42
+ a, a:visited, a:hover {
43
+ color: #0058c4;
44
+ text-decoration: underline;
45
+ }
46
+
47
+ /*p {
48
+ margin: 0px 1em;
49
+ line-height: 1.5em;
50
+ color: black;
51
+ }*/
52
+
53
+ h1 {
54
+ font-size: 150%;
55
+ color: black;
56
+ font-weight: bold;
57
+ }
58
+
59
+ h2 {
60
+ font-size: 120%;
61
+ color: black;
62
+ }
63
+ /* End General Element Styles */
64
+
65
+ .max_width {
66
+ width: 100%;
67
+ }
68
+
69
+ .mid_width {
70
+ width: 75%;
71
+ }
72
+
73
+ .min_width {
74
+ width: 40%;
75
+ }
76
+
77
+ .align_right {
78
+ text-align: right;
79
+ }
80
+
81
+ .align_left {
82
+ text-align: left;
83
+ }
84
+
85
+ .align_center {
86
+ text-align: center;
87
+ }
88
+
89
+ .red_text p {
90
+ text-align: center;
91
+ font-size: 100%;
92
+ color: red;
93
+ }
94
+
95
+ /* End General Element Styles */
96
+
97
+
98
+ .note {
99
+ color: red;
100
+ font-weight: bold;
101
+ }
102
+
103
+ .error {
104
+ margin-bottom: 2em;
105
+ background-color: #c40d0d;
106
+ text-align: center;
107
+ font-size: 110%;
108
+ padding: 1px;
109
+ border: 1px solid gray;
110
+ color: white;
111
+ }
112
+
113
+ .notice {
114
+ margin-bottom: 2em;
115
+ background-color: #dbffb4;
116
+ text-align: center;
117
+ font-family: arial;
118
+ padding: 1px;
119
+ border: 1px solid gray;
120
+ color: black;
121
+ }
122
+
123
+ #footer {
124
+ margin: 1em;
125
+ text-align: center;
126
+ margin: 1em;
127
+ }
128
+
129
+ div.button_widget {
130
+ margin: .2em 0em .4em 0em;
131
+ }
132
+
133
+ .button_widget form, .button_widget div {
134
+ display: inline;
135
+ }
136
+
137
+ div.new_record_widget a {
138
+ color: #fe7600;
139
+ font-weight: bold;
140
+ font-size: 14px;
141
+ }
142
+
143
+ div.button_widget a, div.button_widget {
144
+ font-size: 14px;
145
+ }
146
+
147
+ #logout_link {
148
+ color: #fe7600;
149
+ }
150
+
151
+
152
+ /********* tables *********/
153
+
154
+ input[readonly], textarea[readonly] {
155
+ border: 1px dotted #bcbcbc;
156
+ padding: 2px;
157
+ }
158
+
159
+ table {
160
+ vertical-align: top;
161
+ border: 1px solid black;
162
+ border-collapse: collapse;
163
+ margin: 0 0 1.5em 0;
164
+ }
165
+
166
+ table td {
167
+ border: 1px solid black;
168
+ padding: 0px 5px;
169
+ color: black;
170
+ }
171
+
172
+ table th {
173
+ border: 1px solid black;
174
+ color: black;
175
+ background-color: #ccc;
176
+ white-space: nowrap;
177
+ padding: 0px 5px;
178
+ text-align: left;
179
+ }
180
+
181
+ table.vertical th {
182
+ background-color: #eee;
183
+ white-space: nowrap;
184
+ text-align: right;
185
+ }
186
+
187
+ caption {
188
+ font-weight: bold;
189
+ color: white;
190
+ background-color: #26A;
191
+ border: 1px solid black;
192
+ text-align: center;
193
+ padding: 4px;
194
+ font-size: 110%;
195
+ }
196
+
197
+ table.horizontal th {
198
+ background-color: #fff;
199
+ text-align: left;
200
+ font-size: 90%;
201
+ }
202
+
203
+ table tbody.highlight tr:hover {
204
+ background-color: #ffd;
205
+ }
206
+
207
+ .blue {
208
+ padding: 2px 5px;
209
+ border: 1px solid black;
210
+ border-bottom: 0px;
211
+ color: white;
212
+ background-color: #58B;
213
+ font-size: 110%;
214
+ font-weight: bold;
215
+ text-align: left;
216
+ margin: 0px;
217
+ }
218
+
219
+ .empty_result_set {
220
+ font-weight: bold;
221
+ text-align: center;
222
+ border: 1px solid black;
223
+ }
224
+
225
+ /** tabbed navigation **/
226
+
227
+ #navbar_footer {
228
+ clear: both;
229
+ margin: 0;
230
+ padding: 0;
231
+ width: 100%;
232
+ /* sync these values, line-height is needed for IE */
233
+ height: 4px;
234
+ line-height: 4px;
235
+ border-bottom: 1px solid #9C9C9C;
236
+ background: #81BBF2;
237
+ }
238
+
239
+ #navbar ul {
240
+ clear: both;
241
+ display: block;
242
+ margin: 0;
243
+ background-color: gray;
244
+ font-size: 15px;
245
+ }
246
+
247
+ #navbar li {
248
+ float: left;
249
+ display: block;
250
+ margin: 0 2px;
251
+ padding: 0px 5px;
252
+ border: 1px solid #9C9C9C;
253
+ background-color: #ffffff;
254
+ border-bottom: none;
255
+ white-space: nowrap;
256
+ }
257
+
258
+ #navbar li a, #navbar li a:visited {
259
+ color: black;
260
+ text-decoration: none;
261
+ }
262
+
263
+ #navbar li.current a {
264
+ font-weight: bold;
265
+ }
266
+
267
+ #navbar li:hover {
268
+ background: #CCCCCC;
269
+ }
270
+
271
+ #navbar li.current, #navbar li.current:hover {
272
+ background-color: #81bbf2;
273
+ }
274
+
275
+ .ucb_rails_security_form label {
276
+ width: 8em;
277
+ float: left;
278
+ text-align: right;
279
+ margin-right: 0.5em;
280
+ display: block;
281
+ font-size: 1em;
282
+ padding-right: 2px;
283
+ font-weight: bold;
284
+ }
285
+
286
+ .ucb_rails_security_form input[type=text] {
287
+ font-size: .9em;
288
+ }
289
+
290
+ .ucb_rails_security_form select[multiple] {
291
+ font-size: .8em;
292
+ padding: .5em;
293
+ margin-top: 0px;
294
+ width: 350px;
295
+ }
296
+
297
+
298
+ .ucb_rails_security_form fieldset {
299
+ width: 65%;
300
+ overflow: visible;
301
+ border: 1px solid #999999;
302
+ }
303
+
304
+ .ucb_rails_security_form legend {
305
+ background-color: #efefef;
306
+ font-family: sans-serif;
307
+ padding: 0em .5em;
308
+ border: 1px solid black;
309
+ font-size: .8em;
310
+ font-weight: bold;
311
+ }
312
+
313
+ div.button_widget {
314
+ margin-left: 6em;
315
+ }
316
+
317
+ .fieldWithErrors {
318
+ padding: 2px;
319
+ background-color: red;
320
+ display: table;
321
+ }
322
+
323
+
324
+
325
+ table.doubleSelectList {
326
+ border: 0px solid white;
327
+ }
328
+
329
+ table.doubleSelectList td {
330
+ text-align: center;
331
+ vertical-align: top;
332
+ border: 0px solid white;
333
+ }
334
+
335
+ table.doubleSelectList td.buttons {
336
+ text-align: center;
337
+ vertical-align: middle;
338
+ color: gray;
339
+ border: 0px solid white;
340
+ }
341
+
342
+ .doubleSelectList select[multiple] {
343
+ font-size: .8em;
344
+ padding: .5em;
345
+ margin-top: 0px;
346
+ width: 350px;
347
+ }
@@ -0,0 +1,10 @@
1
+ <div id="navbar">
2
+ <ul>
3
+ <% users_class = params[:controller] =~ /users/ ? "class='current'" : "" %>
4
+ <% roles_class = params[:controller] =~ /roles/ ? "class='current'" : "" %>
5
+ <% help_class = params[:controller] =~ /help/ ? "class='current'" : "" %>
6
+ <li <%= users_class %>><%= link_to('Users', ucb_security_users_path()) %></li>
7
+ <li <%= roles_class %>><%= link_to('Roles', ucb_security_roles_path()) %></li>
8
+ </ul>
9
+ </div>
10
+ <div id="navbar_footer"><hr style="display:none;"></div>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
3
+ <head>
4
+ <title>UCB Rails Security - <%= @title %></title>
5
+ <%= stylesheet_link_tag 'ucb_security' %>
6
+ <%= javascript_include_tag :defaults, 'ucb_security' %>
7
+ </head>
8
+
9
+ <body>
10
+ <div id="site_header">
11
+ UCB Rails Security
12
+ </div>
13
+
14
+ <div id="container">
15
+ <%= render :partial => 'layouts/ucb_security/main_navigation' %>
16
+
17
+ <div id="main">
18
+ <div id="message"><%= display_message() %></div>
19
+ <h1><%= @title %></h1>
20
+ <%= yield %>
21
+ </div>
22
+ </div>
23
+ </body>
24
+ </html>