milia 0.3.30 → 0.3.31
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -4
- data/Gemfile.lock +31 -28
- data/{README.rdoc → README.md} +182 -31
- data/Rakefile +9 -9
- data/VERSION +1 -1
- data/app/controllers/registrations_controller.rb +1 -1
- data/markdown.rb +38 -0
- data/milia.gemspec +12 -17
- metadata +53 -39
data/Gemfile
CHANGED
@@ -3,17 +3,16 @@ source "http://rubygems.org"
|
|
3
3
|
# Example:
|
4
4
|
# gem "activesupport", ">= 2.3.5"
|
5
5
|
|
6
|
-
gem 'rails', '
|
7
|
-
gem 'devise', "
|
6
|
+
gem 'rails', '3.1.3'
|
7
|
+
gem 'devise', "2.1.2"
|
8
8
|
|
9
9
|
# Add dependencies to develop your gem here.
|
10
10
|
# Include everything needed to run rake, tests, features, etc.
|
11
11
|
group :development, :test do
|
12
12
|
gem 'pg'
|
13
13
|
gem "shoulda", ">= 0"
|
14
|
-
gem "bundler", "~> 1.0.0"
|
15
14
|
gem "jeweler", "~> 1.6.4"
|
16
|
-
gem "rcov", ">= 0"
|
15
|
+
# gem "rcov", ">= 0"
|
17
16
|
gem 'rdoc'
|
18
17
|
gem 'turn', :require => false
|
19
18
|
end
|
data/Gemfile.lock
CHANGED
@@ -29,40 +29,41 @@ GEM
|
|
29
29
|
activesupport (= 3.1.3)
|
30
30
|
activesupport (3.1.3)
|
31
31
|
multi_json (~> 1.0)
|
32
|
-
ansi (1.4.
|
33
|
-
arel (2.2.
|
32
|
+
ansi (1.4.3)
|
33
|
+
arel (2.2.3)
|
34
34
|
bcrypt-ruby (3.0.1)
|
35
|
-
builder (3.0.
|
36
|
-
devise (1.
|
35
|
+
builder (3.0.4)
|
36
|
+
devise (2.1.2)
|
37
37
|
bcrypt-ruby (~> 3.0)
|
38
|
-
orm_adapter (~> 0.
|
39
|
-
|
38
|
+
orm_adapter (~> 0.1)
|
39
|
+
railties (~> 3.1)
|
40
|
+
warden (~> 1.2.1)
|
40
41
|
erubis (2.7.0)
|
41
42
|
git (1.2.5)
|
42
43
|
hike (1.2.1)
|
43
|
-
i18n (0.6.
|
44
|
+
i18n (0.6.1)
|
44
45
|
jeweler (1.6.4)
|
45
46
|
bundler (~> 1.0)
|
46
47
|
git (>= 1.2.5)
|
47
48
|
rake
|
48
|
-
json (1.
|
49
|
-
mail (2.3.
|
49
|
+
json (1.7.5)
|
50
|
+
mail (2.3.3)
|
50
51
|
i18n (>= 0.4.0)
|
51
52
|
mime-types (~> 1.16)
|
52
53
|
treetop (~> 1.4.8)
|
53
|
-
mime-types (1.
|
54
|
-
multi_json (1.
|
55
|
-
orm_adapter (0.0
|
56
|
-
pg (0.
|
54
|
+
mime-types (1.19)
|
55
|
+
multi_json (1.3.7)
|
56
|
+
orm_adapter (0.4.0)
|
57
|
+
pg (0.14.1)
|
57
58
|
polyglot (0.3.3)
|
58
|
-
rack (1.3.
|
59
|
-
rack-cache (1.
|
59
|
+
rack (1.3.6)
|
60
|
+
rack-cache (1.2)
|
60
61
|
rack (>= 0.4)
|
61
62
|
rack-mount (0.8.3)
|
62
63
|
rack (>= 1.0.0)
|
63
64
|
rack-ssl (1.3.2)
|
64
65
|
rack
|
65
|
-
rack-test (0.6.
|
66
|
+
rack-test (0.6.2)
|
66
67
|
rack (>= 1.0)
|
67
68
|
rails (3.1.3)
|
68
69
|
actionmailer (= 3.1.3)
|
@@ -80,35 +81,37 @@ GEM
|
|
80
81
|
rdoc (~> 3.4)
|
81
82
|
thor (~> 0.14.6)
|
82
83
|
rake (0.9.2.2)
|
83
|
-
|
84
|
-
rdoc (3.11)
|
84
|
+
rdoc (3.12)
|
85
85
|
json (~> 1.4)
|
86
|
-
shoulda (
|
87
|
-
|
86
|
+
shoulda (3.3.2)
|
87
|
+
shoulda-context (~> 1.0.1)
|
88
|
+
shoulda-matchers (~> 1.4.1)
|
89
|
+
shoulda-context (1.0.1)
|
90
|
+
shoulda-matchers (1.4.1)
|
91
|
+
activesupport (>= 3.0.0)
|
92
|
+
sprockets (2.0.4)
|
88
93
|
hike (~> 1.2)
|
89
94
|
rack (~> 1.0)
|
90
95
|
tilt (~> 1.1, != 1.3.0)
|
91
96
|
thor (0.14.6)
|
92
97
|
tilt (1.3.3)
|
93
|
-
treetop (1.4.
|
98
|
+
treetop (1.4.12)
|
94
99
|
polyglot
|
95
100
|
polyglot (>= 0.3.1)
|
96
|
-
turn (0.
|
101
|
+
turn (0.9.6)
|
97
102
|
ansi
|
98
|
-
tzinfo (0.3.
|
99
|
-
warden (1.1
|
103
|
+
tzinfo (0.3.35)
|
104
|
+
warden (1.2.1)
|
100
105
|
rack (>= 1.0)
|
101
106
|
|
102
107
|
PLATFORMS
|
103
108
|
ruby
|
104
109
|
|
105
110
|
DEPENDENCIES
|
106
|
-
|
107
|
-
devise (>= 1.4.8)
|
111
|
+
devise (= 2.1.2)
|
108
112
|
jeweler (~> 1.6.4)
|
109
113
|
pg
|
110
|
-
rails (
|
111
|
-
rcov
|
114
|
+
rails (= 3.1.3)
|
112
115
|
rdoc
|
113
116
|
shoulda
|
114
117
|
turn
|
data/{README.rdoc → README.md}
RENAMED
@@ -1,9 +1,10 @@
|
|
1
|
-
|
1
|
+
# milia
|
2
2
|
|
3
3
|
Milia is a multi-tenanting gem for hosted Rails 3.1 applications which use
|
4
4
|
devise for user authentication.
|
5
5
|
|
6
|
-
|
6
|
+
## Basic concepts
|
7
|
+
|
7
8
|
* should be transparent to the main application code
|
8
9
|
* should be symbiotic with user authentication
|
9
10
|
* should raise exceptions upon attempted illegal access
|
@@ -20,55 +21,71 @@ performance hit, was seriously time-consuming to backup and restore, was invasiv
|
|
20
21
|
into the Rails code structure (monkey patching), was complex to implement, and
|
21
22
|
couldn't use Rails migration tools as-is.
|
22
23
|
|
23
|
-
|
24
|
+
## Structure
|
25
|
+
|
24
26
|
* necessary models: user, tenant
|
25
27
|
* necessary migrations: user, tenant, tenants_users (join table)
|
26
28
|
|
27
|
-
|
29
|
+
## Dependency requirements
|
30
|
+
|
28
31
|
* Rails 3.1 or higher
|
29
32
|
* Devise 1.4.8 or higher
|
30
33
|
|
31
|
-
|
34
|
+
## Installation
|
32
35
|
|
33
36
|
Either install the gem manually:
|
34
37
|
|
35
|
-
|
38
|
+
```
|
39
|
+
$ gem install milia
|
40
|
+
```
|
36
41
|
|
37
42
|
Or in the Gemfile:
|
38
43
|
|
44
|
+
```ruby
|
39
45
|
gem 'milia'
|
46
|
+
```
|
40
47
|
|
41
|
-
|
48
|
+
## Getting started
|
49
|
+
|
50
|
+
### Rails setup
|
42
51
|
|
43
|
-
=== Rails setup
|
44
52
|
Milia expects a user session, so please set one up
|
45
53
|
|
54
|
+
```
|
46
55
|
$ rails g session_migration
|
47
56
|
invoke active_record
|
48
57
|
create db/migrate/20111012060818_add_sessions_table.rb
|
58
|
+
```
|
49
59
|
|
50
|
-
|
60
|
+
### Devise setup
|
61
|
+
|
51
62
|
* See https://github.com/plataformatec/devise for how to set up devise.
|
52
63
|
* The current version of milia requires that devise use a *User* model.
|
53
64
|
|
54
|
-
|
65
|
+
### Milia setup
|
66
|
+
|
67
|
+
#### migrations
|
55
68
|
|
56
|
-
==== migrations
|
57
69
|
*ALL* models require a tenanting field, whether they are to be universal or to
|
58
70
|
be tenanted. So make sure the following is added to each migration
|
59
71
|
|
60
72
|
<i>db/migrate</i>
|
61
73
|
|
74
|
+
```ruby
|
62
75
|
t.references :tenant
|
76
|
+
```
|
63
77
|
|
64
78
|
Tenanted models will also require indexes for the tenant field:
|
65
79
|
|
80
|
+
```ruby
|
66
81
|
add_index :TABLE, :tenant_id
|
82
|
+
```
|
67
83
|
|
68
84
|
Also create a tenants_users join table:
|
69
85
|
|
70
86
|
<i>db/migrate/20111008081639_create_tenants_users.rb</i>
|
71
87
|
|
88
|
+
```ruby
|
72
89
|
class CreateTenantsUsers < ActiveRecord::Migration
|
73
90
|
def change
|
74
91
|
create_table :tenants_users, :id => false do |t|
|
@@ -79,43 +96,83 @@ Also create a tenants_users join table:
|
|
79
96
|
add_index :tenants_users, :user_id
|
80
97
|
end
|
81
98
|
end
|
99
|
+
```
|
100
|
+
|
101
|
+
#### application controller
|
82
102
|
|
83
|
-
==== application controller
|
84
103
|
add the following line AFTER the devise-required filter for authentications:
|
85
104
|
|
86
105
|
<i>app/controllers/application_controller.rb</i>
|
87
106
|
|
88
|
-
|
89
|
-
before_filter :
|
107
|
+
```ruby
|
108
|
+
before_filter :authenticate_tenant! # authenticate user and setup tenant
|
109
|
+
|
110
|
+
# ------------------------------------------------------------------------------
|
111
|
+
# authenticate_tenant! -- authorization & tenant setup
|
112
|
+
# -- authenticates user
|
113
|
+
# -- sets current tenant
|
114
|
+
# -- sets up app environment for this user
|
115
|
+
# ------------------------------------------------------------------------------
|
116
|
+
def authenticate_tenant!()
|
117
|
+
|
118
|
+
unless authenticate_user!
|
119
|
+
email = ( params.nil? || params[:user].nil? ? "" : " as: " + params[:user][:email] )
|
120
|
+
|
121
|
+
flash[:notice] = "cannot sign you in#{email}; check email/password and try again"
|
122
|
+
|
123
|
+
return false # abort the before_filter chain
|
124
|
+
end
|
125
|
+
|
126
|
+
# user_signed_in? == true also means current_user returns valid user
|
127
|
+
raise SecurityError,"*** invalid sign-in ***" unless user_signed_in?
|
128
|
+
|
129
|
+
set_current_tenant # relies on current_user being non-nil
|
130
|
+
|
131
|
+
# any application-specific environment set up goes here
|
132
|
+
|
133
|
+
true # allows before filter chain to continue
|
134
|
+
end
|
135
|
+
|
136
|
+
```
|
137
|
+
|
90
138
|
|
91
139
|
catch any exceptions with the following (be sure to also add the designated methods!)
|
92
140
|
|
141
|
+
```ruby
|
93
142
|
rescue_from ::Milia::Control::MaxTenantExceeded, :with => :max_tenants
|
94
143
|
rescue_from ::Milia::Control::InvalidTenantAccess, :with => :invalid_tenant
|
144
|
+
```
|
145
|
+
|
146
|
+
#### routes
|
95
147
|
|
96
|
-
==== routes
|
97
148
|
Add the following line into the devise_for :users block
|
98
149
|
|
99
150
|
<i>config/routes.rb</i>
|
100
151
|
|
152
|
+
```ruby
|
101
153
|
devise_for :users do
|
102
154
|
post "users" => "milia/registrations#create"
|
103
155
|
end
|
156
|
+
```
|
104
157
|
|
105
|
-
|
158
|
+
### Designate which model determines account
|
159
|
+
|
106
160
|
Add the following acts_as_... to designate which model will be used as the key
|
107
161
|
into tenants_users to find the tenant for a given user.
|
108
162
|
Only designate one model in this manner.
|
109
163
|
|
110
164
|
<i>app/models/user.rb</i>
|
111
165
|
|
166
|
+
```ruby
|
112
167
|
class User < ActiveRecord::Base
|
113
168
|
|
114
169
|
acts_as_universal_and_determines_account
|
115
170
|
|
116
171
|
end # class User
|
172
|
+
```
|
173
|
+
|
174
|
+
### Designate which model determines tenant
|
117
175
|
|
118
|
-
=== Designate which model determines tenant
|
119
176
|
Add the following acts_as_... to designate which model will be used as the
|
120
177
|
tenant model. It is this id field which designates the tenant for an entire
|
121
178
|
group of users which exist within a single tenanted domain.
|
@@ -123,54 +180,71 @@ Only designate one model in this manner.
|
|
123
180
|
|
124
181
|
<i>app/models/tenant.rb</i>
|
125
182
|
|
183
|
+
```ruby
|
126
184
|
class Tenant < ActiveRecord::Base
|
127
185
|
|
128
186
|
acts_as_universal_and_determines_tenant
|
129
187
|
|
130
188
|
end # class Tenant
|
189
|
+
```
|
190
|
+
|
191
|
+
### Designate universal models
|
131
192
|
|
132
|
-
=== Designate universal models
|
133
193
|
Add the following acts_as_universal to *ALL* models which are to be universal and
|
134
194
|
remove any superfluous
|
135
195
|
|
196
|
+
```ruby
|
136
197
|
belongs_to :tenant
|
198
|
+
```
|
137
199
|
|
138
200
|
which the generator might have generated ( acts_as_tenant will specify that ).
|
139
201
|
|
140
202
|
<i>app/models/eula.rb</i>
|
141
203
|
|
204
|
+
```ruby
|
142
205
|
class Eula < ActiveRecord::Base
|
143
206
|
|
144
207
|
acts_as_universal
|
145
208
|
|
146
209
|
end # class Eula
|
210
|
+
```
|
211
|
+
|
212
|
+
### Designate tenanted models
|
147
213
|
|
148
|
-
=== Designate tenanted models
|
149
214
|
Add the following acts_as_tenant to *ALL* models which are to be tenanted and
|
150
215
|
remove any superfluous
|
151
216
|
|
217
|
+
```ruby
|
152
218
|
belongs_to :tenant
|
219
|
+
```
|
153
220
|
|
154
221
|
which the generator might have generated ( acts_as_tenant will specify that ).
|
155
222
|
|
156
223
|
<i>app/models/post.rb</i>
|
157
224
|
|
225
|
+
```ruby
|
158
226
|
class Post < ActiveRecord::Base
|
159
227
|
|
160
228
|
acts_as_tenant
|
161
229
|
|
162
230
|
end # class Post
|
231
|
+
```
|
163
232
|
|
164
233
|
|
165
|
-
|
234
|
+
### Exceptions raised
|
166
235
|
|
236
|
+
```ruby
|
167
237
|
Milia::Control::InvalidTenantAccess
|
168
238
|
Milia::Control::MaxTenantExceeded
|
239
|
+
```
|
169
240
|
|
170
|
-
|
171
|
-
Milia expects a tenant pre-processing & setup hook:
|
241
|
+
### Tenant pre-processing hooks
|
172
242
|
|
243
|
+
#### Milia expects a tenant pre-processing & setup hook:
|
244
|
+
|
245
|
+
```ruby
|
173
246
|
Tenant.create_new_tenant(params) # see sample code below
|
247
|
+
```
|
174
248
|
|
175
249
|
where the sign-up params are passed, the new tenant must be validated, created,
|
176
250
|
and then returned. Any other kinds of prepatory processing are permitted here,
|
@@ -180,21 +254,54 @@ immediately after the new tenant has been created).
|
|
180
254
|
|
181
255
|
<i>app/models/tenant.rb</i>
|
182
256
|
|
257
|
+
```ruby
|
183
258
|
def self.create_new_tenant(params)
|
184
259
|
|
185
|
-
tenant
|
260
|
+
tenant # Tenant.new(:cname => params[:user][:email], :company => params[:tenant][:company])
|
186
261
|
|
187
262
|
if new_signups_not_permitted?(params)
|
188
263
|
|
189
|
-
raise MaxTenantExceeded, "Sorry, new accounts not permitted at this time"
|
264
|
+
raise ::Milia::Control::MaxTenantExceeded, "Sorry, new accounts not permitted at this time"
|
190
265
|
|
191
266
|
else
|
192
267
|
tenant.save # create the tenant
|
193
268
|
end
|
194
269
|
return tenant
|
195
270
|
end
|
271
|
+
```
|
272
|
+
|
273
|
+
#### Milia expects a tenant post-processing hook:
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
Tenant.tenant_signup(user,tenant,other) # see sample code below
|
277
|
+
```
|
278
|
+
|
279
|
+
The purpose here is to do any tenant initialization AFTER devise
|
280
|
+
has validated and created a user. Objects for the user and tenant
|
281
|
+
are passed. It is recommended that only minimal processing be done
|
282
|
+
here ... for example, queueing a background task to do the actual
|
283
|
+
work in setting things up for a new tenant.
|
284
|
+
|
285
|
+
<i>app/models/tenant.rb</i>
|
286
|
+
|
287
|
+
```ruby
|
288
|
+
# ------------------------------------------------------------------------
|
289
|
+
# tenant_signup -- setup a new tenant in the system
|
290
|
+
# CALLBACK from devise RegistrationsController (milia override)
|
291
|
+
# AFTER user creation and current_tenant established
|
292
|
+
# args:
|
293
|
+
# user -- new user obj
|
294
|
+
# tenant -- new tenant obj
|
295
|
+
# other -- any other parameter string from initial request
|
296
|
+
# ------------------------------------------------------------------------
|
297
|
+
def self.tenant_signup(user, tenant, other = nil)
|
298
|
+
StartupJob.queue_startup( tenant, user, other )
|
299
|
+
end
|
300
|
+
```
|
301
|
+
|
302
|
+
|
303
|
+
### Alternate use case: user belongs to multiple tenants
|
196
304
|
|
197
|
-
=== Alternate use case: user belongs to multiple tenants
|
198
305
|
Your application might allow a user to belong to multiple tenants. You will need
|
199
306
|
to provide some type of mechanism to allow the user to choose which account
|
200
307
|
(thus tenant) they wish to access. Once chosen, in your controller, you will need
|
@@ -202,18 +309,63 @@ to put:
|
|
202
309
|
|
203
310
|
<i>app/controllers/any_controller.rb</i>
|
204
311
|
|
312
|
+
```ruby
|
205
313
|
set_current_tenant( new_tenant_id )
|
314
|
+
```
|
315
|
+
|
316
|
+
## joins might require additional tenanting restrictions
|
317
|
+
|
318
|
+
Subordinate join tables will not get the Rails default scope.
|
319
|
+
Theoretically, the default scope on the master table alone should be sufficient
|
320
|
+
in restricting answers to the current_tenant alone .. HOWEVER, it doesn't feel
|
321
|
+
right.
|
322
|
+
|
323
|
+
If the master table for the join is a universal table, however, you really *MUST*
|
324
|
+
use the following workaround, otherwise the database will access data in other
|
325
|
+
tenanted areas even if no records are returned. This is a potential security
|
326
|
+
breach. Further details can be found in various discussions about the
|
327
|
+
behavior of databases such as POSTGRES.
|
328
|
+
|
329
|
+
The milia workaround is to add an additional .where( where_restrict_tenants(klass1, klass2,...))
|
330
|
+
for each of the subordinate models in the join.
|
331
|
+
|
332
|
+
### usage of where_restrict_tenants
|
333
|
+
|
334
|
+
```ruby
|
335
|
+
Comment.joins(stuff).where( where_restrict_tenants(Post, Author) ).all
|
336
|
+
```
|
337
|
+
|
338
|
+
## console
|
339
|
+
|
340
|
+
Note that even when running the console ($ rails console) will be run in
|
341
|
+
multi-tenanting mode. You will need to establish a current_user and
|
342
|
+
setup the current_tenant, otherwise most Model DB accesses will fail.
|
343
|
+
|
344
|
+
For the author's own application, I have set up a small ruby file which I
|
345
|
+
load when I start the console. This does the following:
|
346
|
+
|
347
|
+
```ruby
|
348
|
+
def change_tenant(my_id,my_tenant_id)
|
349
|
+
@me = User.find( my_id )
|
350
|
+
@w = Tenant.find( my_tenant_id )
|
351
|
+
Tenant.set_current_tenant @w
|
352
|
+
end
|
353
|
+
|
354
|
+
change_tenant(1,1) # or whatever is an appropriate starting user, tenant
|
355
|
+
```
|
356
|
+
|
357
|
+
|
206
358
|
|
359
|
+
## Cautions
|
207
360
|
|
208
|
-
|
209
|
-
* Milia designates a default_scope for all models (both universal and tenanted). From Rails 3.2 onwards, the last designated default scope overrides any prior scopes.
|
361
|
+
* Milia designates a default_scope for all models (both universal and tenanted). From Rails 3.2 onwards, the last designated default scope overrides any prior scopes and will invalidate multi-tenanting; so *DO NOT USE default_scope*
|
210
362
|
* Milia uses Thread.current[:tenant_id] to hold the current tenant for the existing Action request in the application.
|
211
363
|
* SQL statements executed outside the context of ActiveRecord pose a potential danger; the current milia implementation does not extend to the DB connection level and so cannot enforce tenanting at this point.
|
212
364
|
* The tenant_id of a universal model will always be forced to nil.
|
213
365
|
* The tenant_id of a tenanted model will be set to the current_tenant of the current_user upon creation.
|
214
366
|
|
215
367
|
|
216
|
-
|
368
|
+
## Contributing to milia
|
217
369
|
|
218
370
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
219
371
|
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
@@ -223,8 +375,7 @@ to put:
|
|
223
375
|
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
224
376
|
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
225
377
|
|
226
|
-
|
378
|
+
## Copyright
|
227
379
|
|
228
|
-
Copyright (c) 2011 Daudi Amani. See LICENSE.txt for
|
229
|
-
further details.
|
380
|
+
Copyright (c) 2011 Daudi Amani. See LICENSE.txt for further details.
|
230
381
|
|
data/Rakefile
CHANGED
@@ -34,15 +34,15 @@ Rake::TestTask.new(:test) do |test|
|
|
34
34
|
test.verbose = true
|
35
35
|
end
|
36
36
|
|
37
|
-
require 'rcov/rcovtask'
|
38
|
-
Rcov::RcovTask.new do |test|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
task :default => :test
|
37
|
+
# require 'rcov/rcovtask'
|
38
|
+
# Rcov::RcovTask.new do |test|
|
39
|
+
# test.libs << 'test'
|
40
|
+
# test.pattern = 'test/**/test_*.rb'
|
41
|
+
# test.verbose = true
|
42
|
+
# test.rcov_opts << '--exclude "gems/*"'
|
43
|
+
# end
|
44
|
+
|
45
|
+
# task :default => :test
|
46
46
|
|
47
47
|
require 'rdoc/task'
|
48
48
|
Rake::RDocTask.new do |rdoc|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.31
|
@@ -77,7 +77,7 @@ end # def create
|
|
77
77
|
sign_in(resource_name, resource)
|
78
78
|
respond_with resource, :location => after_sign_up_path_for(resource)
|
79
79
|
else
|
80
|
-
set_flash_message :notice, :inactive_signed_up, :reason =>
|
80
|
+
set_flash_message :notice, :inactive_signed_up, :reason => resource.inactive_message if is_navigational_format?
|
81
81
|
expire_session_data_after_sign_in!
|
82
82
|
respond_with resource, :location => after_inactive_sign_up_path_for(resource)
|
83
83
|
end
|
data/markdown.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'redcarpet'
|
5
|
+
|
6
|
+
class ShowMd
|
7
|
+
|
8
|
+
TEMPFILE = "/tmp/markdown.html"
|
9
|
+
|
10
|
+
def initialize( file )
|
11
|
+
@body = IO.read( file )
|
12
|
+
end
|
13
|
+
|
14
|
+
def markdown
|
15
|
+
options = [ :autolink, :no_intraemphasis, :fenced_code, :gh_blockcode]
|
16
|
+
|
17
|
+
File.open( TEMPFILE, "w" ) do |file|
|
18
|
+
file.write( RedcarpetCompat.new( @body, *options).to_html )
|
19
|
+
end # do file
|
20
|
+
end
|
21
|
+
|
22
|
+
def show
|
23
|
+
system("chromium-browser #{TEMPFILE} &")
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
end # class
|
28
|
+
|
29
|
+
md = ShowMd.new( ARGV[0] )
|
30
|
+
md.markdown
|
31
|
+
md.show
|
32
|
+
|
33
|
+
# puts RedcarpetCompat.new(ARGF.read,
|
34
|
+
# :fenced_code,
|
35
|
+
# :hard_wrap,
|
36
|
+
# :filter_html,
|
37
|
+
# :smart).to_html
|
38
|
+
|
data/milia.gemspec
CHANGED
@@ -5,16 +5,16 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "milia"
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.31"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["David Anderson"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2012-11-05"
|
13
13
|
s.description = "Transparent Multi-tenanting for hosted Rails 3.1+/Ruby 1.9.2 applications"
|
14
14
|
s.email = "dsaronin@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
|
-
"README.
|
17
|
+
"README.md"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
".document",
|
@@ -24,7 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
"Gemfile",
|
25
25
|
"Gemfile.lock",
|
26
26
|
"LICENSE.txt",
|
27
|
-
"README.
|
27
|
+
"README.md",
|
28
28
|
"Rakefile",
|
29
29
|
"VERSION",
|
30
30
|
"app/controllers/registrations_controller.rb",
|
@@ -34,6 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
"lib/milia/control.rb",
|
35
35
|
"lib/milia/railtie.rb",
|
36
36
|
"lib/milia/tasks.rb",
|
37
|
+
"markdown.rb",
|
37
38
|
"milia.gemspec",
|
38
39
|
"test/helper.rb",
|
39
40
|
"test/rails_app/.gitignore",
|
@@ -126,41 +127,35 @@ Gem::Specification.new do |s|
|
|
126
127
|
s.homepage = "http://github.com/dsaronin/milia"
|
127
128
|
s.licenses = ["MIT"]
|
128
129
|
s.require_paths = ["lib"]
|
129
|
-
s.rubygems_version = "1.8.
|
130
|
+
s.rubygems_version = "1.8.24"
|
130
131
|
s.summary = "Multi-tenanting for hosted Rails 3.1+ applications"
|
131
132
|
|
132
133
|
if s.respond_to? :specification_version then
|
133
134
|
s.specification_version = 3
|
134
135
|
|
135
136
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
136
|
-
s.add_runtime_dependency(%q<rails>, ["
|
137
|
-
s.add_runtime_dependency(%q<devise>, ["
|
137
|
+
s.add_runtime_dependency(%q<rails>, ["= 3.1.3"])
|
138
|
+
s.add_runtime_dependency(%q<devise>, ["= 2.1.2"])
|
138
139
|
s.add_development_dependency(%q<pg>, [">= 0"])
|
139
140
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
140
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
141
141
|
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
142
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
143
142
|
s.add_development_dependency(%q<rdoc>, [">= 0"])
|
144
143
|
s.add_development_dependency(%q<turn>, [">= 0"])
|
145
144
|
else
|
146
|
-
s.add_dependency(%q<rails>, ["
|
147
|
-
s.add_dependency(%q<devise>, ["
|
145
|
+
s.add_dependency(%q<rails>, ["= 3.1.3"])
|
146
|
+
s.add_dependency(%q<devise>, ["= 2.1.2"])
|
148
147
|
s.add_dependency(%q<pg>, [">= 0"])
|
149
148
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
150
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
151
149
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
152
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
153
150
|
s.add_dependency(%q<rdoc>, [">= 0"])
|
154
151
|
s.add_dependency(%q<turn>, [">= 0"])
|
155
152
|
end
|
156
153
|
else
|
157
|
-
s.add_dependency(%q<rails>, ["
|
158
|
-
s.add_dependency(%q<devise>, ["
|
154
|
+
s.add_dependency(%q<rails>, ["= 3.1.3"])
|
155
|
+
s.add_dependency(%q<devise>, ["= 2.1.2"])
|
159
156
|
s.add_dependency(%q<pg>, [">= 0"])
|
160
157
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
161
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
162
158
|
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
163
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
164
159
|
s.add_dependency(%q<rdoc>, [">= 0"])
|
165
160
|
s.add_dependency(%q<turn>, [">= 0"])
|
166
161
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: milia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.31
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,33 +9,43 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-11-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
21
|
+
version: 3.1.3
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - '='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 3.1.3
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: devise
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
|
-
- -
|
35
|
+
- - '='
|
31
36
|
- !ruby/object:Gem::Version
|
32
|
-
version: 1.
|
37
|
+
version: 2.1.2
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - '='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 2.1.2
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: pg
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,10 +53,15 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: shoulda
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,21 +69,15 @@ dependencies:
|
|
54
69
|
version: '0'
|
55
70
|
type: :development
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
58
|
-
- !ruby/object:Gem::Dependency
|
59
|
-
name: bundler
|
60
|
-
requirement: &74906980 !ruby/object:Gem::Requirement
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
61
73
|
none: false
|
62
74
|
requirements:
|
63
|
-
- -
|
75
|
+
- - ! '>='
|
64
76
|
- !ruby/object:Gem::Version
|
65
|
-
version:
|
66
|
-
type: :development
|
67
|
-
prerelease: false
|
68
|
-
version_requirements: *74906980
|
77
|
+
version: '0'
|
69
78
|
- !ruby/object:Gem::Dependency
|
70
79
|
name: jeweler
|
71
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
72
81
|
none: false
|
73
82
|
requirements:
|
74
83
|
- - ~>
|
@@ -76,10 +85,15 @@ dependencies:
|
|
76
85
|
version: 1.6.4
|
77
86
|
type: :development
|
78
87
|
prerelease: false
|
79
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 1.6.4
|
80
94
|
- !ruby/object:Gem::Dependency
|
81
|
-
name:
|
82
|
-
requirement:
|
95
|
+
name: rdoc
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
83
97
|
none: false
|
84
98
|
requirements:
|
85
99
|
- - ! '>='
|
@@ -87,21 +101,15 @@ dependencies:
|
|
87
101
|
version: '0'
|
88
102
|
type: :development
|
89
103
|
prerelease: false
|
90
|
-
version_requirements:
|
91
|
-
- !ruby/object:Gem::Dependency
|
92
|
-
name: rdoc
|
93
|
-
requirement: &74903050 !ruby/object:Gem::Requirement
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
105
|
none: false
|
95
106
|
requirements:
|
96
107
|
- - ! '>='
|
97
108
|
- !ruby/object:Gem::Version
|
98
109
|
version: '0'
|
99
|
-
type: :development
|
100
|
-
prerelease: false
|
101
|
-
version_requirements: *74903050
|
102
110
|
- !ruby/object:Gem::Dependency
|
103
111
|
name: turn
|
104
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
105
113
|
none: false
|
106
114
|
requirements:
|
107
115
|
- - ! '>='
|
@@ -109,14 +117,19 @@ dependencies:
|
|
109
117
|
version: '0'
|
110
118
|
type: :development
|
111
119
|
prerelease: false
|
112
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
113
126
|
description: Transparent Multi-tenanting for hosted Rails 3.1+/Ruby 1.9.2 applications
|
114
127
|
email: dsaronin@gmail.com
|
115
128
|
executables: []
|
116
129
|
extensions: []
|
117
130
|
extra_rdoc_files:
|
118
131
|
- LICENSE.txt
|
119
|
-
- README.
|
132
|
+
- README.md
|
120
133
|
files:
|
121
134
|
- .document
|
122
135
|
- .project
|
@@ -125,7 +138,7 @@ files:
|
|
125
138
|
- Gemfile
|
126
139
|
- Gemfile.lock
|
127
140
|
- LICENSE.txt
|
128
|
-
- README.
|
141
|
+
- README.md
|
129
142
|
- Rakefile
|
130
143
|
- VERSION
|
131
144
|
- app/controllers/registrations_controller.rb
|
@@ -135,6 +148,7 @@ files:
|
|
135
148
|
- lib/milia/control.rb
|
136
149
|
- lib/milia/railtie.rb
|
137
150
|
- lib/milia/tasks.rb
|
151
|
+
- markdown.rb
|
138
152
|
- milia.gemspec
|
139
153
|
- test/helper.rb
|
140
154
|
- test/rails_app/.gitignore
|
@@ -238,7 +252,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
238
252
|
version: '0'
|
239
253
|
segments:
|
240
254
|
- 0
|
241
|
-
hash:
|
255
|
+
hash: -744736145
|
242
256
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
243
257
|
none: false
|
244
258
|
requirements:
|
@@ -247,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
247
261
|
version: '0'
|
248
262
|
requirements: []
|
249
263
|
rubyforge_project:
|
250
|
-
rubygems_version: 1.8.
|
264
|
+
rubygems_version: 1.8.24
|
251
265
|
signing_key:
|
252
266
|
specification_version: 3
|
253
267
|
summary: Multi-tenanting for hosted Rails 3.1+ applications
|