ucb_rails_security 2.0.7

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 (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>