kaui 0.7.2 → 0.8.0

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 (76) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +1 -2
  4. data/Gemfile.lock +59 -38
  5. data/README.md +12 -9
  6. data/Rakefile +9 -0
  7. data/{lib/generators/kaui/install/templates/app/assets/javascripts/kaui/all.js → app/assets/javascripts/application.js} +2 -5
  8. data/{lib/generators/kaui/install/templates/app/assets/stylesheets/kaui/all.css → app/assets/stylesheets/application.css} +0 -4
  9. data/app/assets/stylesheets/bootstrap_and_overrides.css +7 -0
  10. data/app/controllers/kaui/admin_allowed_users_controller.rb +48 -0
  11. data/app/controllers/kaui/admin_tenants_controller.rb +97 -0
  12. data/app/controllers/kaui/engine_controller.rb +28 -31
  13. data/app/controllers/kaui/engine_controller_util.rb +33 -0
  14. data/app/controllers/kaui/login_proxy_controller.rb +11 -0
  15. data/app/controllers/kaui/sessions_controller.rb +12 -0
  16. data/app/controllers/kaui/tenants_controller.rb +60 -0
  17. data/app/models/kaui/ability.rb +20 -3
  18. data/app/models/kaui/admin_tenant.rb +10 -0
  19. data/app/models/kaui/allowed_user.rb +8 -0
  20. data/app/models/kaui/allowed_user_tenant.rb +6 -0
  21. data/app/models/kaui/killbill_authenticatable.rb +5 -18
  22. data/app/models/kaui/tenant.rb +13 -0
  23. data/app/models/kaui/user.rb +14 -16
  24. data/app/views/kaui/admin_allowed_users/index.html.erb +23 -0
  25. data/app/views/kaui/admin_allowed_users/new.html.erb +22 -0
  26. data/app/views/kaui/admin_allowed_users/show.html.erb +53 -0
  27. data/app/views/kaui/admin_tenants/index.html.erb +25 -0
  28. data/app/views/kaui/admin_tenants/new.html.erb +32 -0
  29. data/app/views/kaui/admin_tenants/show.html.erb +68 -0
  30. data/app/views/kaui/invoices/show.html.erb +1 -1
  31. data/app/views/kaui/tenants/index.html.erb +17 -0
  32. data/config/initializers/killbill_authenticatable.rb +3 -5
  33. data/config/locales/en.bootstrap.yml +18 -0
  34. data/config/routes.rb +27 -1
  35. data/config/symmetric-encryption.yml +135 -0
  36. data/db/ddl.sql +33 -2
  37. data/db/migrate/20130812155313_devise_create_kaui_users.rb +1 -3
  38. data/db/migrate/20150109214021_create_kaui_tenants.rb +12 -0
  39. data/db/migrate/20150112232813_create_kaui_allowed_users.rb +19 -0
  40. data/kaui.gemspec +5 -3
  41. data/lib/kaui.rb +49 -1
  42. data/lib/kaui/version.rb +1 -1
  43. data/test/dummy/config/application.rb +3 -0
  44. data/test/dummy/config/database.yml +9 -0
  45. data/test/dummy/config/environments/development.rb +2 -2
  46. data/test/dummy/config/initializers/killbill_client.rb +2 -0
  47. data/test/dummy/config/symmetric-encryption.yml +135 -0
  48. data/test/dummy/db/migrate/{20130819152643_devise_create_kaui_users.kaui.rb → 20150116052157_devise_create_kaui_users.kaui.rb} +1 -3
  49. data/test/dummy/db/migrate/20150116052158_create_kaui_tenants.kaui.rb +13 -0
  50. data/test/dummy/db/migrate/20150116052159_create_kaui_allowed_users.kaui.rb +20 -0
  51. data/test/dummy/db/schema.rb +29 -3
  52. data/test/functional/kaui/admin_allowed_users_controller_test.rb +30 -0
  53. data/test/functional/kaui/admin_tenants_controller_test.rb +35 -0
  54. data/test/functional/kaui/functional_test_helper.rb +2 -50
  55. data/test/functional/kaui/functional_test_helper_nosetup.rb +53 -0
  56. data/test/functional/kaui/invoices_controller_test.rb +22 -0
  57. data/test/functional/kaui/tenants_controller_test.rb +60 -0
  58. data/test/integration/kaui/integration_test_helper.rb +2 -0
  59. data/test/integration/kaui/navigation_test.rb +1 -2
  60. data/test/killbill_test_helper.rb +46 -4
  61. data/test/test_helper.rb +1 -0
  62. data/test/unit/helpers/kaui/admin_allowed_users_helper_test.rb +6 -0
  63. data/test/unit/helpers/kaui/admin_tenants_helper_test.rb +6 -0
  64. data/test/unit/helpers/kaui/tenants_helper_test.rb +6 -0
  65. data/test/unit/kaui/allowed_user_test.rb +34 -0
  66. data/test/unit/kaui/tenant_test.rb +19 -0
  67. data/vendor/assets/javascripts/jquery.dataTables.min.js +155 -0
  68. metadata +86 -21
  69. data/app/assets/javascripts/kaui/analytics.js +0 -71
  70. data/app/assets/stylesheets/kaui/analytics.css +0 -30
  71. data/test/dummy/app/assets/javascripts/application.js +0 -21
  72. data/test/dummy/app/assets/stylesheets/application.css +0 -15
  73. data/test/dummy/app/views/layouts/application.html.erb +0 -48
  74. data/vendor/assets/javascripts/js/bootstrap-datepicker.cd46d38.js +0 -1211
  75. data/vendor/assets/javascripts/js/bootstrap.v2.2.1.min.js +0 -6
  76. data/vendor/assets/javascripts/js/jquery.dataTables.v1.9.3.min.js +0 -156
@@ -1,18 +1,16 @@
1
1
  class Kaui::EngineController < ApplicationController
2
- before_filter :authenticate_user!
2
+
3
+ include Kaui::EngineControllerUtil
4
+
5
+ before_filter :authenticate_user!, :check_for_redirect_to_tenant_screen
3
6
 
4
7
  layout :get_layout
5
8
 
6
9
  # Common options for the Kill Bill client
7
10
  def options_for_klient(options = {})
8
- {
9
- # TODO Kaui doesn't support multi-tenancy yet
10
- :api_key => KillBillClient.api_key,
11
- :api_secret => KillBillClient.api_secret,
12
- :username => current_user.kb_username || KillBillClient.username,
13
- :password => current_user.password || KillBillClient.password,
14
- :session_id => current_user.kb_session_id
15
- }.merge(options)
11
+ user_tenant_options = Kaui.current_tenant_user_options(current_user, session)
12
+ user_tenant_options.merge(options)
13
+ user_tenant_options
16
14
  end
17
15
 
18
16
  # Used for auditing purposes
@@ -20,38 +18,37 @@ class Kaui::EngineController < ApplicationController
20
18
  super
21
19
  end
22
20
 
21
+
23
22
  def current_ability
24
23
  # Redefined here to namespace Ability in the correct module
25
24
  @current_ability ||= Kaui::Ability.new(current_user)
26
25
  end
27
26
 
28
- protected
29
-
30
- def as_string(e)
31
- if e.is_a?(KillBillClient::API::ResponseError)
32
- "Error #{e.response.code}: #{as_string_from_response(e.response.body)}"
33
- else
34
- e.message
27
+ def check_for_redirect_to_tenant_screen
28
+ if !Kaui.is_user_assigned_valid_tenant?(current_user, session)
29
+ flash[:error] = "No tenants configured for users AND KillBillClient.api_key, KillBillClient.api_secret have not been set"
30
+ session[:kb_tenant_id] = nil
31
+ redirect_to Kaui.tenant_home_path.call and return
35
32
  end
36
33
  end
37
34
 
38
- def as_string_from_response(response)
39
- error_message = response
40
- begin
41
- # BillingExceptionJson?
42
- error_message = JSON.parse response
43
- rescue => e
44
- end
45
35
 
46
- if error_message.respond_to? :[] and error_message['message'].present?
47
- # Likely BillingExceptionJson
48
- error_message = error_message['message']
36
+ private
37
+
38
+ def current_tenant_user
39
+ user = current_user
40
+ kb_tenant_id = session[:kb_tenant_id]
41
+ user_tenant = Kaui::Tenant.find_by_kb_tenant_id(kb_tenant_id) if kb_tenant_id
42
+ result = {
43
+ :username => user.kb_username,
44
+ :password => user.password,
45
+ :session_id => user.kb_session_id,
46
+ }
47
+ if user_tenant
48
+ result[:api_key] = user_tenant.api_key
49
+ result[:api_secret] = user_tenant.api_secret
49
50
  end
50
- # Limit the error size to avoid ActionDispatch::Cookies::CookieOverflow
51
- error_message[0..1000]
51
+ result
52
52
  end
53
53
 
54
- def get_layout
55
- layout ||= Kaui.config[:layout]
56
- end
57
54
  end
@@ -0,0 +1,33 @@
1
+ module Kaui::EngineControllerUtil
2
+
3
+ protected
4
+
5
+ def get_layout
6
+ layout ||= Kaui.config[:layout]
7
+ end
8
+
9
+ def as_string(e)
10
+ if e.is_a?(KillBillClient::API::ResponseError)
11
+ "Error #{e.response.code}: #{as_string_from_response(e.response.body)}"
12
+ else
13
+ e.message
14
+ end
15
+ end
16
+
17
+ def as_string_from_response(response)
18
+ error_message = response
19
+ begin
20
+ # BillingExceptionJson?
21
+ error_message = JSON.parse response
22
+ rescue => e
23
+ end
24
+
25
+ if error_message.respond_to? :[] and error_message['message'].present?
26
+ # Likely BillingExceptionJson
27
+ error_message = error_message['message']
28
+ end
29
+ # Limit the error size to avoid ActionDispatch::Cookies::CookieOverflow
30
+ error_message[0..1000]
31
+ end
32
+
33
+ end
@@ -0,0 +1,11 @@
1
+ module Kaui
2
+ class LoginProxyController < Kaui::EngineController
3
+
4
+ def check_login
5
+ #
6
+ # Redirect to where we come from after going through all the Kaui filters ensuring correct authentication and kb_tenant_id
7
+ #
8
+ redirect_to params['path']
9
+ end
10
+ end
11
+ end
@@ -2,5 +2,17 @@ module Kaui
2
2
  # Subclassed to specify the correct layout
3
3
  class SessionsController < Devise::SessionsController
4
4
  layout Kaui.config[:layout]
5
+
6
+ skip_before_filter :check_for_redirect_to_tenant_screen
7
+
8
+ protected
9
+
10
+ # Override after_sign_in_path_for to not have to rely on the default 'root' config which we want to keep on home#index
11
+ def after_sign_in_path_for(resource)
12
+ # Clear the tenant_id from the cookie to not rely on old cookie data
13
+ session[:kb_tenant_id] = nil
14
+ Kaui.tenant_home_path.call
15
+ end
16
+
5
17
  end
6
18
  end
@@ -0,0 +1,60 @@
1
+ module Kaui
2
+ class TenantsController < Kaui::EngineController
3
+
4
+ skip_before_filter :check_for_redirect_to_tenant_screen
5
+
6
+ def index
7
+ begin
8
+
9
+ # Retrieve current user and extract allowed list of tenants
10
+ user = current_user
11
+ allowed_user = Kaui::AllowedUser.find_by_kb_username(user.kb_username)
12
+ @tenants = (allowed_user.kaui_tenants if allowed_user) || []
13
+
14
+ #
15
+ # If there is nothing we check for override with KillBillClient.api_key/KillBillClient.api_secret
16
+ # If there is only one, we skip the tenant screen since the choice is obvious
17
+ # If not, we allow user to chose what he wants
18
+ #
19
+ case @tenants.size
20
+ when 0
21
+ # If KillBillClient.api_key and KillBillClient.api_secret are not set, the client library will throw
22
+ # an KillBillClient::API::Unauthorized exception which will end up in the rescue below
23
+ tenant = KillBillClient::Model::Tenant.find_by_api_key(KillBillClient.api_key, {
24
+ :session_id => user.kb_session_id
25
+ })
26
+ kb_tenant_id = tenant.tenant_id if tenant.present?
27
+ select_tenant_for_tenant_id(kb_tenant_id)
28
+ when 1
29
+ # If there is only one tenant defined we skip the screen and set the tenant for the user
30
+ select_tenant_for_tenant_id(@tenants[0].kb_tenant_id)
31
+ else
32
+ # Jump to default view allowing to chose which tenant to pick
33
+ respond_to do |format|
34
+ format.html # index.html.erb
35
+ format.json { render :json => @tenants }
36
+ end
37
+ end
38
+ rescue => e
39
+ flash[:error] = "Error while retrieving tenants: No tenants configured for users AND KillBillClient.api_key, KillBillClient.api_secret have not been set"
40
+ @tenants = []
41
+ # We then display the view with NO tenants and the flash error so user understands he does not have any configured tenants available
42
+ end
43
+
44
+ end
45
+
46
+ def select_tenant
47
+ kb_tenant_id = params[:kb_tenant_id]
48
+ select_tenant_for_tenant_id(kb_tenant_id)
49
+ end
50
+
51
+ private
52
+
53
+ def select_tenant_for_tenant_id(kb_tenant_id)
54
+ # Set kb_tenant_id in the session
55
+ session[:kb_tenant_id] = kb_tenant_id
56
+ redirect_to Kaui.home_path.call
57
+ end
58
+
59
+ end
60
+ end
@@ -7,19 +7,36 @@ module Kaui
7
7
  user.permissions.each do |permission|
8
8
  # permission is something like invoice:item_adjust or payment:refund
9
9
  # We rely on a naming convention where the left part refers to a Kaui model
10
- model, action = permission.split(':')
10
+ model, action = permission_to_model_action(permission)
11
11
  if model == '*' and action == '*'
12
12
  # All permissions!
13
13
  can :manage, :all
14
14
  elsif model == '*' and action != '*'
15
15
  # TODO
16
16
  elsif action == '*'
17
- can :all, ('Kaui::' + model.capitalize).constantize rescue nil
17
+ # TODO Not sure the :all is really working (but we don't use it)
18
+ can :all, ('Kaui::' + model.camelize).constantize rescue nil
18
19
  else
19
- can action.to_sym, ('Kaui::' + model.capitalize).constantize rescue nil
20
+ can action.to_sym, ('Kaui::' + model.camelize).constantize rescue nil
20
21
  end
21
22
  end
22
23
  rescue KillBillClient::API::Unauthorized => e
23
24
  end
25
+
26
+ def permission_to_model_action(permission)
27
+ #
28
+ # Permissions are defined in Kill Kill apis (https://github.com/killbill/killbill-api/blob/master/src/main/java/org/killbill/billing/security/Permission.java)
29
+ # and they look something like 'invoice:item_adjust' or 'payment:refund', where the first part is the Kill Bill module and the second the action.
30
+ #
31
+ # For most of those the Kill Bill module maps to the Kaui model, but for a few, the naming convention breaks, so in order to keep the API clean, we do the fix up
32
+ # in KAUI itself:
33
+ #
34
+ to_be_model, action = permission.split(':')
35
+ # Currently the only actions implemented for overdue and catalog (upload_config) are those implemented at the tenant level:
36
+ if to_be_model == 'tenant' || 'overdue' || 'catalog'
37
+ to_be_model = 'admin_tenant'
38
+ end
39
+ [to_be_model, action]
40
+ end
24
41
  end
25
42
  end
@@ -0,0 +1,10 @@
1
+ class Kaui::AdminTenant < KillBillClient::Model::Tenant
2
+
3
+
4
+ class << self
5
+ def upload_catalog(catalog_xml, user = nil, reason = nil, comment = nil, options = {})
6
+ KillBillClient::Model::Catalog.upload_tenant_catalog(catalog_xml, user, reason, comment, options)
7
+ end
8
+ end
9
+
10
+ end
@@ -0,0 +1,8 @@
1
+ module Kaui
2
+ class AllowedUser < ActiveRecord::Base
3
+ attr_accessible :kb_username, :description
4
+
5
+ has_many :kaui_allowed_user_tenants, :class_name => 'Kaui::AllowedUserTenant', :foreign_key => 'kaui_allowed_user_id'
6
+ has_many :kaui_tenants, :through => :kaui_allowed_user_tenants, :source => :kaui_tenant, :uniq => true
7
+ end
8
+ end
@@ -0,0 +1,6 @@
1
+ module Kaui
2
+ class AllowedUserTenant < ActiveRecord::Base
3
+ belongs_to :kaui_allowed_user, :class_name => 'Kaui::AllowedUser', :foreign_key => 'kaui_allowed_user_id'
4
+ belongs_to :kaui_tenant, :class_name => 'Kaui::Tenant', :foreign_key => 'kaui_tenant_id'
5
+ end
6
+ end
@@ -5,10 +5,10 @@ module Devise
5
5
  module KillbillAuthenticatable
6
6
  extend ActiveSupport::Concern
7
7
 
8
- def valid_killbill_password?(kb_username, kb_password, api_key, api_secret)
8
+ def valid_killbill_password?(kb_username, kb_password)
9
9
  # Simply try to look-up the permissions for that user - this will
10
10
  # Take care of the auth part
11
- response = Kaui::User.find_permissions(kb_username, kb_password, api_key, api_secret)
11
+ response = Kaui::User.find_permissions(kb_username, kb_password)
12
12
  # Auth was successful, update the session id
13
13
  self.kb_session_id = response.session_id
14
14
  true
@@ -24,22 +24,9 @@ module Devise
24
24
 
25
25
  # Invoked by the KillbillAuthenticatable strategy to lookup the user
26
26
  # before attempting authentication
27
- def find_for_killbill_authentication(kb_username, kb_password, api_key, api_secret)
28
- kb_tenant_id = nil
29
-
30
- # Only in the Multi-Tenancy usecase
31
- if api_key.present?
32
- tenant = KillBillClient::Model::Tenant.find_by_api_key api_key, {
33
- :username => kb_username,
34
- :password => kb_password,
35
- :api_key => api_key,
36
- :api_secret => api_secret
37
- }
38
- kb_tenant_id = tenant.tenant_id if tenant.present?
39
- end
40
-
41
- find_for_authentication(:kb_tenant_id => kb_tenant_id, :kb_username => kb_username) ||
42
- new(:kb_tenant_id => kb_tenant_id, :kb_username => kb_username)
27
+ def find_for_killbill_authentication(kb_username)
28
+ find_for_authentication(:kb_username => kb_username) ||
29
+ new(:kb_username => kb_username)
43
30
  rescue KillBillClient::API::Unauthorized => e
44
31
  # Multi-Tenancy was enabled, but the tenant_id couldn't be retrieved because of bad credentials
45
32
  nil
@@ -0,0 +1,13 @@
1
+ require 'symmetric-encryption'
2
+
3
+ module Kaui
4
+ class Tenant < ActiveRecord::Base
5
+
6
+ attr_accessible :name, :api_key, :api_secret, :kb_tenant_id
7
+ attr_encrypted :api_secret
8
+
9
+ has_many :kaui_allowed_user_tenants, :class_name => 'Kaui::AllowedUserTenant', :foreign_key => 'kaui_tenant_id'
10
+ has_many :kaui_allowed_users, :through => :kaui_allowed_user_tenants, :source => :kaui_allowed_user
11
+
12
+ end
13
+ end
@@ -7,33 +7,31 @@ module Kaui
7
7
  # Managed by Devise
8
8
  attr_accessor :password
9
9
 
10
- attr_accessible :kb_tenant_id, :kb_username, :kb_session_id, :password
10
+ attr_accessible :kb_username, :kb_session_id, :password
11
11
 
12
12
  # Called by Devise to perform authentication
13
13
  # Throws KillBillClient::API::Unauthorized on failure
14
- def self.find_permissions(kb_username, kb_password, api_key=KillBillClient.api_key, api_secret=KillBillClient.api_secret)
14
+ def self.find_permissions(kb_username, kb_password)
15
15
  do_find_permissions :username => kb_username,
16
- :password => kb_password,
17
- :api_key => api_key,
18
- :api_secret => api_secret
16
+ :password => kb_password
19
17
  end
20
18
 
21
19
  # Called by CanCan to perform authorization
22
20
  # Throws KillBillClient::API::Unauthorized on failure
23
- def permissions(api_key=KillBillClient.api_key, api_secret=KillBillClient.api_secret)
24
- User.do_find_permissions :session_id => kb_session_id,
25
- :api_key => api_key,
26
- :api_secret => api_secret
21
+ def permissions()
22
+ User.do_find_permissions :session_id => kb_session_id
27
23
  end
28
24
 
29
25
  # Verify the Kill Bill session hasn't timed-out
30
- def authenticated_with_killbill?(api_key=KillBillClient.api_key, api_secret=KillBillClient.api_secret)
31
- subject = KillBillClient::Model::Security.find_subject :session_id => kb_session_id,
32
- :api_key => api_key,
33
- :api_secret => api_secret
34
- subject.is_authenticated
35
- rescue KillBillClient::API::Unauthorized => e
36
- false
26
+ def authenticated_with_killbill?()
27
+
28
+ begin
29
+ subject = KillBillClient::Model::Security.find_subject :session_id => kb_session_id
30
+ result = subject.is_authenticated
31
+ return result
32
+ rescue KillBillClient::API::Unauthorized => e
33
+ false
34
+ end
37
35
  end
38
36
 
39
37
  private
@@ -0,0 +1,23 @@
1
+ <% if can? :view, Kaui::AdminTenant %>
2
+ <% unless @allowed_users.empty? %>
3
+ <table id="allowed-users-table" class="table table-condensed">
4
+ <thead>
5
+ <tr>
6
+ <th>Name</th>
7
+ <th>Description</th>
8
+ </tr>
9
+ </thead>
10
+ <tbody>
11
+ <% @allowed_users.each do |u | %>
12
+ <tr>
13
+ <td><%= link_to u.kb_username, admin_allowed_user_path(u.id) %></td>
14
+ <td><%= u.description %></td>
15
+ </tr>
16
+ <% end %>
17
+ </tbody>
18
+ </table>
19
+ <% end %>
20
+ <% end %>
21
+ <% if can? :create, Kaui::AdminTenant %>
22
+ <h3><%= link_to 'Add a new Allowed User', new_admin_allowed_user_path %></h3>
23
+ <% end %>
@@ -0,0 +1,22 @@
1
+ <% if can? :create, Kaui::AdminTenant %>
2
+ <%= form_for @allowed_user, url: admin_allowed_users_path, :html => {:class => 'form-horizontal'} do |f| %>
3
+ <fieldset>
4
+ <div class="control-group">
5
+ <%= f.label :kb_username, 'Name', :class => 'control-label' %>
6
+ <div class="controls">
7
+ <%= f.text_field :kb_username, :class => 'input-small', :required => true %>
8
+ </div>
9
+ </div>
10
+ <div class="control-group">
11
+ <%= f.label :description, 'Description', :class => 'control-label' %>
12
+ <div class="controls">
13
+ <%= f.text_field :description, :class => 'input-small', :required => false %>
14
+ </div>
15
+ </div>
16
+ <div class="form-actions">
17
+ <%= button_tag 'Configure a new Allowed User', :class => 'btn btn-primary' %>
18
+ </div>
19
+ </fieldset>
20
+ <% end %>
21
+ <% end %>
22
+
@@ -0,0 +1,53 @@
1
+ <% if can? :view, Kaui::AdminTenant %>
2
+ <dl class="dl-horizontal">
3
+ <dt>Name:</dt>
4
+ <dd><%= @allowed_user.kb_username %>&nbsp;</dd>
5
+ <dt>Tenant ID:</dt>
6
+ <dd><%= @allowed_user.description %>&nbsp;</dd>
7
+ </dl>
8
+
9
+ <% unless @allowed_user.kaui_tenants.empty? %>
10
+ <h3>Configured tenants:</h3>
11
+ <table id="allowed-user-tenants-table" class="table table-condensed">
12
+ <thead>
13
+ <tr>
14
+ <th>Name</th>
15
+ <th>Tenant Id</th>
16
+ <th>Api Key</th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <% @allowed_user.kaui_tenants.each do |t| %>
21
+ <tr>
22
+ <td><%= link_to t.name, admin_tenant_path(t.id) %></td>
23
+ <td><%= t.kb_tenant_id %></td>
24
+ <td><%= t.api_key %></td>
25
+ </tr>
26
+ <% end %>
27
+ </tbody>
28
+ </table>
29
+ <% end %>
30
+ <% end %>
31
+
32
+ <% if can? :create, Kaui::AdminTenant %>
33
+ <%= form_for(@allowed_user, :url => {:action => :add_tenant}, :html => {:method => :post, :class => "form-horizontal"}) do |f| %>
34
+
35
+ <fieldset>
36
+ <%= f.hidden_field(:id) %>
37
+ <div class="control-group">
38
+ <%= label_tag :tenant_name, "Available Tenants:", :class => "control-label" %>
39
+ <div class="controls">
40
+ <%= select_tag :tenant_id, options_for_select(@tenants.map { |t| [t.name, t.id] }) %>
41
+ </div>
42
+ </div>
43
+ <div class="form-actions">
44
+ <%= f.submit 'Chose Tenant', :class => 'btn btn-primary' %>
45
+ <%= link_to 'Back', :back, :class => 'btn' %>
46
+ </div>
47
+ </fieldset>
48
+ <% end %>
49
+ <% end %>
50
+
51
+ <div class="form-actions">
52
+ <%= link_to 'Back', :back, :class => 'btn' %>
53
+ </div>