curupira 0.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of curupira might be problematic. Click here for more details.

Files changed (181) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +19 -0
  5. data/Gemfile +17 -0
  6. data/Gemfile.lock +202 -0
  7. data/README.md +72 -0
  8. data/Rakefile +31 -0
  9. data/app/controllers/curupira/authorized_controller.rb +9 -0
  10. data/app/controllers/curupira/groups_controller.rb +43 -0
  11. data/app/controllers/curupira/passwords_controller.rb +46 -0
  12. data/app/controllers/curupira/roles_controller.rb +43 -0
  13. data/app/controllers/curupira/sessions_controller.rb +30 -0
  14. data/app/controllers/curupira/users_controller.rb +47 -0
  15. data/app/helpers/curupira/authorize_helper.rb +21 -0
  16. data/app/helpers/curupira/relationship_select_options_helper.rb +17 -0
  17. data/app/mailers/curupira/reset_password_mailer.rb +13 -0
  18. data/app/views/curupira/groups/_form.html.erb +28 -0
  19. data/app/views/curupira/groups/_role_group_fields.html.erb +9 -0
  20. data/app/views/curupira/groups/edit.html.erb +3 -0
  21. data/app/views/curupira/groups/index.html.erb +24 -0
  22. data/app/views/curupira/groups/new.html.erb +3 -0
  23. data/app/views/curupira/groups/show.html.erb +32 -0
  24. data/app/views/curupira/passwords/edit.html.erb +14 -0
  25. data/app/views/curupira/passwords/new.html.erb +14 -0
  26. data/app/views/curupira/reset_password_mailer/instructions.html.erb +19 -0
  27. data/app/views/curupira/reset_password_mailer/reseted.html.erb +7 -0
  28. data/app/views/curupira/roles/_authorization_fields.html.erb +10 -0
  29. data/app/views/curupira/roles/_form.html.erb +23 -0
  30. data/app/views/curupira/roles/edit.html.erb +3 -0
  31. data/app/views/curupira/roles/index.html.erb +24 -0
  32. data/app/views/curupira/roles/new.html.erb +3 -0
  33. data/app/views/curupira/roles/show.html.erb +37 -0
  34. data/app/views/curupira/sessions/new.html.erb +17 -0
  35. data/app/views/curupira/shared/_model_links.html.erb +7 -0
  36. data/app/views/curupira/shared/_session_links.html.erb +7 -0
  37. data/app/views/curupira/users/_form.html.erb +43 -0
  38. data/app/views/curupira/users/_group_user_fields.html.erb +20 -0
  39. data/app/views/curupira/users/_role_group_user_fields.html.erb +10 -0
  40. data/app/views/curupira/users/edit.html.erb +3 -0
  41. data/app/views/curupira/users/index.html.erb +28 -0
  42. data/app/views/curupira/users/new.html.erb +3 -0
  43. data/app/views/curupira/users/show.html.erb +28 -0
  44. data/curupira.gemspec +28 -0
  45. data/lib/curupira.rb +16 -0
  46. data/lib/curupira/authorizer.rb +43 -0
  47. data/lib/curupira/rails.rb +30 -0
  48. data/lib/curupira/rails/routes.rb +15 -0
  49. data/lib/curupira/version.rb +3 -0
  50. data/lib/generators/curupira/controllers/controllers_generator.rb +27 -0
  51. data/lib/generators/curupira/install/install_generator.rb +80 -0
  52. data/lib/generators/curupira/install/model_generators_helper.rb +266 -0
  53. data/lib/generators/curupira/routes/routes_generator.rb +21 -0
  54. data/lib/generators/curupira/routes/templates/routes.rb +1 -0
  55. data/lib/generators/curupira/templates/db/migrate/add_curupira_to_users.rb +20 -0
  56. data/lib/generators/curupira/templates/db/migrate/create_action_labels.rb +12 -0
  57. data/lib/generators/curupira/templates/db/migrate/create_authorizations.rb +12 -0
  58. data/lib/generators/curupira/templates/db/migrate/create_features.rb +11 -0
  59. data/lib/generators/curupira/templates/db/migrate/create_group_users.rb +13 -0
  60. data/lib/generators/curupira/templates/db/migrate/create_groups.rb +10 -0
  61. data/lib/generators/curupira/templates/db/migrate/create_role_group_users.rb +12 -0
  62. data/lib/generators/curupira/templates/db/migrate/create_role_groups.rb +13 -0
  63. data/lib/generators/curupira/templates/db/migrate/create_roles.rb +8 -0
  64. data/lib/generators/curupira/templates/db/migrate/sorcery_core.rb +27 -0
  65. data/lib/generators/curupira/templates/models/action_label.rb +2 -0
  66. data/lib/generators/curupira/templates/models/authorization.rb +2 -0
  67. data/lib/generators/curupira/templates/models/feature.rb +2 -0
  68. data/lib/generators/curupira/templates/models/feature_service.rb +4 -0
  69. data/lib/generators/curupira/templates/models/group.rb +2 -0
  70. data/lib/generators/curupira/templates/models/group_user.rb +2 -0
  71. data/lib/generators/curupira/templates/models/role.rb +2 -0
  72. data/lib/generators/curupira/templates/models/role_group.rb +2 -0
  73. data/lib/generators/curupira/templates/models/role_group_user.rb +2 -0
  74. data/lib/generators/curupira/templates/models/service.rb +2 -0
  75. data/lib/generators/curupira/templates/models/user.rb +2 -0
  76. data/lib/generators/curupira/templates/sorcery.rb +462 -0
  77. data/lib/generators/curupira/views/views_generator.rb +27 -0
  78. data/lib/tasks/curupira_tasks.rake +4 -0
  79. data/spec/app_templates/app/models/action_label.rb +2 -0
  80. data/spec/app_templates/app/models/authorization.rb +2 -0
  81. data/spec/app_templates/app/models/feature.rb +2 -0
  82. data/spec/app_templates/app/models/feature_service.rb +2 -0
  83. data/spec/app_templates/app/models/group.rb +4 -0
  84. data/spec/app_templates/app/models/group_user.rb +2 -0
  85. data/spec/app_templates/app/models/role.rb +2 -0
  86. data/spec/app_templates/app/models/role_group.rb +2 -0
  87. data/spec/app_templates/app/models/role_group_user.rb +2 -0
  88. data/spec/app_templates/app/models/service.rb +2 -0
  89. data/spec/app_templates/app/models/user.rb +2 -0
  90. data/spec/app_templates/config/routes.rb +3 -0
  91. data/spec/controllers/controller_spec.rb +40 -0
  92. data/spec/controllers/groups_controller_spec.rb +162 -0
  93. data/spec/controllers/passwords_controller_spec.rb +171 -0
  94. data/spec/controllers/roles_controller_spec.rb +168 -0
  95. data/spec/controllers/sessions_controller_spec.rb +112 -0
  96. data/spec/controllers/users_controller_spec.rb +182 -0
  97. data/spec/curupira/authorization_spec.rb +67 -0
  98. data/spec/dummy/README.rdoc +28 -0
  99. data/spec/dummy/Rakefile +6 -0
  100. data/spec/dummy/app/assets/images/.keep +0 -0
  101. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  102. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  103. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  104. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  105. data/spec/dummy/app/controllers/home_controller.rb +4 -0
  106. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  107. data/spec/dummy/app/mailers/.keep +0 -0
  108. data/spec/dummy/app/models/.keep +0 -0
  109. data/spec/dummy/app/models/action_label.rb +3 -0
  110. data/spec/dummy/app/models/authorization.rb +4 -0
  111. data/spec/dummy/app/models/feature.rb +3 -0
  112. data/spec/dummy/app/models/group.rb +9 -0
  113. data/spec/dummy/app/models/group_user.rb +7 -0
  114. data/spec/dummy/app/models/role.rb +10 -0
  115. data/spec/dummy/app/models/role_group.rb +4 -0
  116. data/spec/dummy/app/models/role_group_user.rb +4 -0
  117. data/spec/dummy/app/models/user.rb +10 -0
  118. data/spec/dummy/app/views/home/index.html.erb +5 -0
  119. data/spec/dummy/app/views/home/test.html.erb +1 -0
  120. data/spec/dummy/app/views/layouts/application.html.erb +19 -0
  121. data/spec/dummy/bin/bundle +3 -0
  122. data/spec/dummy/bin/rails +4 -0
  123. data/spec/dummy/bin/rake +4 -0
  124. data/spec/dummy/bin/setup +29 -0
  125. data/spec/dummy/config.ru +4 -0
  126. data/spec/dummy/config/application.rb +25 -0
  127. data/spec/dummy/config/boot.rb +5 -0
  128. data/spec/dummy/config/database.yml +25 -0
  129. data/spec/dummy/config/environment.rb +5 -0
  130. data/spec/dummy/config/environments/development.rb +46 -0
  131. data/spec/dummy/config/environments/production.rb +79 -0
  132. data/spec/dummy/config/environments/test.rb +44 -0
  133. data/spec/dummy/config/initializers/assets.rb +11 -0
  134. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  135. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  136. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  137. data/spec/dummy/config/initializers/inflections.rb +16 -0
  138. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  139. data/spec/dummy/config/initializers/session_store.rb +3 -0
  140. data/spec/dummy/config/initializers/sorcery.rb +462 -0
  141. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  142. data/spec/dummy/config/locales/en.yml +23 -0
  143. data/spec/dummy/config/routes.rb +6 -0
  144. data/spec/dummy/config/secrets.yml +22 -0
  145. data/spec/dummy/db/migrate/20150305011941_create_role_group_users.rb +12 -0
  146. data/spec/dummy/db/migrate/20150305011942_create_authorizations.rb +12 -0
  147. data/spec/dummy/db/migrate/20150305011944_create_groups.rb +10 -0
  148. data/spec/dummy/db/migrate/20150305011945_create_roles.rb +8 -0
  149. data/spec/dummy/db/migrate/20150305011946_sorcery_core.rb +27 -0
  150. data/spec/dummy/db/migrate/20150305011947_create_group_users.rb +13 -0
  151. data/spec/dummy/db/migrate/20150305011948_create_role_groups.rb +13 -0
  152. data/spec/dummy/db/migrate/20150312181229_create_action_labels.rb +12 -0
  153. data/spec/dummy/db/migrate/20150312181747_create_features.rb +11 -0
  154. data/spec/dummy/db/schema.rb +112 -0
  155. data/spec/dummy/db/seeds.rb +137 -0
  156. data/spec/dummy/lib/assets/.keep +0 -0
  157. data/spec/dummy/log/.keep +0 -0
  158. data/spec/dummy/public/404.html +67 -0
  159. data/spec/dummy/public/422.html +67 -0
  160. data/spec/dummy/public/500.html +66 -0
  161. data/spec/dummy/public/favicon.ico +0 -0
  162. data/spec/features/link_authorize_spec.rb +25 -0
  163. data/spec/features/list_users_spec.rb +38 -0
  164. data/spec/features/log_in_spec.rb +15 -0
  165. data/spec/generators/curupira/install/action_label_spec.rb +53 -0
  166. data/spec/generators/curupira/install/authorization_generator_spec.rb +51 -0
  167. data/spec/generators/curupira/install/feature_generator_spec.rb +52 -0
  168. data/spec/generators/curupira/install/group_user_generator_spec.rb +51 -0
  169. data/spec/generators/curupira/install/install_generators_spec.rb +159 -0
  170. data/spec/generators/curupira/install/role_generator_spec.rb +38 -0
  171. data/spec/generators/curupira/install/role_group_generator_spec.rb +51 -0
  172. data/spec/generators/curupira/install/role_group_user_generator_spec.rb +52 -0
  173. data/spec/helpers/relationship_select_options_helper_spec.rb +18 -0
  174. data/spec/rails_helper.rb +55 -0
  175. data/spec/spec_helper.rb +87 -0
  176. data/spec/support/factories.rb +64 -0
  177. data/spec/support/generator_spec_helpers.rb +42 -0
  178. data/spec/support/helpers_spec.rb +23 -0
  179. data/spec/support/shared_examples/role_generator_shared_example_spec.rb +13 -0
  180. data/spec/support/sorcery.rb +4 -0
  181. metadata +539 -0
@@ -0,0 +1,17 @@
1
+ <h1>Entrar</h1>
2
+
3
+ <%= form_for @user, url: session_path do |f| %>
4
+ <div class="field">
5
+ <%= f.label :username, "Email ou Nome de usuário" %><br>
6
+ <%= f.text_field :username %>
7
+ </div>
8
+
9
+ <div class="field">
10
+ <%= f.label :password, "Senha" %><br>
11
+ <%= f.password_field :password %>
12
+ </div>
13
+
14
+ <%= f.submit "Entrar" %>
15
+ <% end %>
16
+
17
+ <%= link_to "Esqueci minha senha", new_password_path %>
@@ -0,0 +1,7 @@
1
+ <% if current_user %>
2
+ <div id="curupira-model-links">
3
+ <%= link_to "Usuários", users_path %><br>
4
+ <%= link_to "Grupos de Usuário", groups_path %><br>
5
+ <%= link_to "Perfis", roles_path %>
6
+ </div>
7
+ <% end %>
@@ -0,0 +1,7 @@
1
+ <div id="curupira-session-links">
2
+ <% if current_user %>
3
+ <%= link_to "Sair", destroy_session_path %>
4
+ <% else %>
5
+ <%= link_to "Entrar", new_session_path %>
6
+ <% end %>
7
+ </div>
@@ -0,0 +1,43 @@
1
+ <%= form_for @user do |f| %>
2
+ <div class="field">
3
+ <%= f.label :email, "Email" %><br>
4
+ <%= f.email_field :email %>
5
+ </div>
6
+
7
+ <div class="field">
8
+ <%= f.label :name, "Nome" %><br>
9
+ <%= f.text_field :name %>
10
+ </div>
11
+
12
+ <div class="field">
13
+ <%= f.label :username, "Nome de usuário" %><br>
14
+ <%= f.text_field :username %>
15
+ </div>
16
+
17
+ <div class="field">
18
+ <%= f.label :password, "Senha" %><br>
19
+ <%= f.password_field :password %>
20
+ </div>
21
+
22
+ <div class="field">
23
+ <%= f.label :active, "Ativo" %><br>
24
+ <%= f.check_box :active %>
25
+ </div>
26
+
27
+ <div class="group_users">
28
+ <h3>Grupos</h3>
29
+
30
+ <%= f.fields_for :group_users do |b| %>
31
+ <%= render 'group_user_fields', f: b %>
32
+ <% end %>
33
+
34
+ <div class="links">
35
+ <%= link_to_add_association 'Adicionar grupo', f, :group_users %>
36
+ </div>
37
+ </div>
38
+
39
+ <div class="actions">
40
+ <%= f.submit %><br>
41
+ or <%= link_to :cancel, users_path %>
42
+ </div>
43
+ <% end %>
@@ -0,0 +1,20 @@
1
+ <div class="nested-fields">
2
+ <% if f.object.group.blank? || f.object.group.active? %>
3
+ <%= f.select :group_id, active_user_groups_select_options(current_user) %>
4
+ <% else %>
5
+ <%= f.object.user_group.name %>
6
+ <% end %>
7
+
8
+ <div style="margin: 50px">
9
+ <h4>Perfis</h4>
10
+ <%= f.fields_for :role_group_users do |role_group_user| %>
11
+ <%= render "role_group_user_fields", f: role_group_user %>
12
+ <% end %>
13
+
14
+ <div class="links">
15
+ <%= link_to_add_association 'Adicionar Permissão', f, :role_group_users %>
16
+ </div>
17
+
18
+ <%= link_to_remove_association "Remover", f %>
19
+ </div>
20
+ </div>
@@ -0,0 +1,10 @@
1
+ <div class="nested-fields">
2
+ <% if f.object.role.blank? || f.object.role.active? %>
3
+
4
+ <%= f.select :role_id, active_roles_select_options %>
5
+ <% else %>
6
+ <%= f.object.role.name %>
7
+ <% end %>
8
+
9
+ <%= link_to_remove_association "Remover", f %>
10
+ </div>
@@ -0,0 +1,3 @@
1
+ <h1>Editar Usuário</h1>
2
+
3
+ <%= render "form" %>
@@ -0,0 +1,28 @@
1
+ <h1>Usuários</h1>
2
+
3
+ <div class="actions">
4
+ <%= link_to "Novo", new_user_path %>
5
+ </div>
6
+
7
+ <table>
8
+ <thead>
9
+ <tr>
10
+ <th>Nome</th>
11
+ <th>Email</th>
12
+ <th>Nome de usuário</th>
13
+ <th>Ativo</th>
14
+ <th></th>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ <% @users.each do |user| %>
19
+ <tr>
20
+ <td><%= link_to user.name, user %></td>
21
+ <td><%= link_to user.email, user %></td>
22
+ <td><%= link_to user.username, user %></td>
23
+ <td><%= user.active %></td>
24
+ <td><%= link_to "Editar", edit_user_path(user) %></td>
25
+ </tr>
26
+ <% end %>
27
+ </tbody>
28
+ </table>
@@ -0,0 +1,3 @@
1
+ <h1>Novo Usuário</h1>
2
+
3
+ <%= render "form" %>
@@ -0,0 +1,28 @@
1
+ <h1>Usuário</h1>
2
+
3
+ <div class="actions">
4
+ <%= link_to "Editar", edit_user_path(@user) %>
5
+ </div>
6
+
7
+ <ul>
8
+ <li>Name: <%= @user.name %></li>
9
+ <li>Email: <%= @user.email %></li>
10
+ <li>Username: <%= @user.username %></li>
11
+ <li>Active: <%= @user.active %></li>
12
+ </ul>
13
+
14
+ <div id="user_groups">
15
+ <h3>Grupos</h3>
16
+
17
+ <ul>
18
+ <% @user.group_users.each do |group_user| %>
19
+ <li><%= group_user.group.name %>
20
+ <% group_user.role_group_users.each do |role_group_user|%>
21
+ <p><%= role_group_user.role.name %></p>
22
+ <% end %>
23
+ </li>
24
+ <% end %>
25
+ </ul>
26
+ </div>
27
+
28
+ <%= link_to "Voltar", users_path %>
data/curupira.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "curupira/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "curupira"
7
+ s.version = Curupira::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Paulo Moura", "Felipe Iketani", "Ricardo Casseb", "Luiz Sanches"]
10
+ s.email = ["paulociecomp@gmail.com", "felipeiketani@gmail.com", "rcasseb@gmail.com", "luizgrsanches@gmail.com"]
11
+ s.homepage = "https://rubygems.org/gems/curupira"
12
+ s.summary = "Curupira!"
13
+ s.description = "Easy way to authentication and authorization"
14
+ s.license = "MIT"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = Dir["spec/**/*"]
18
+ s.require_paths = ["lib"]
19
+
20
+ s.add_dependency "rails", "~> 4.2.0"
21
+ s.add_dependency "sorcery"
22
+ s.add_dependency "cocoon"
23
+ s.add_dependency "jquery-rails"
24
+
25
+ s.add_development_dependency 'rspec-rails'
26
+ s.add_development_dependency 'capybara'
27
+ s.add_development_dependency 'factory_girl_rails'
28
+ end
data/lib/curupira.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "sorcery"
2
+ require "active_support/dependencies"
3
+ require 'rails'
4
+ require 'curupira/authorizer'
5
+
6
+ module Curupira
7
+ mattr_accessor :app_root
8
+
9
+ def self.setup
10
+ yield self
11
+ end
12
+ end
13
+
14
+ require "curupira/rails"
15
+ require 'cocoon'
16
+ require 'jquery-rails'
@@ -0,0 +1,43 @@
1
+ module Curupira
2
+ module Authorizer
3
+ extend ActiveSupport::Concern
4
+
5
+ def authorize_for_group
6
+ unless has_authorization_for_group?
7
+ deny_access
8
+ end
9
+ end
10
+
11
+ def authorize
12
+ unless has_authorization?
13
+ deny_access
14
+ end
15
+ end
16
+
17
+ def has_authorization?
18
+ return true if current_user.admin?
19
+ query(params).present?
20
+ end
21
+
22
+ def has_authorization_for(params)
23
+ query(params).present?
24
+ end
25
+
26
+ private
27
+
28
+ def deny_access
29
+ redirect_to "/", notice: "Sem autorização"
30
+ end
31
+
32
+ def query(params)
33
+ User.joins(
34
+ role_group_users: { role: { features: [:action_labels] } }
35
+ )
36
+ .where(
37
+ features: { controller: params[:controller] },
38
+ action_labels: { name: params[:action] },
39
+ id: current_user
40
+ )
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ require 'curupira/rails/routes'
2
+
3
+ module Curupira
4
+ class Engine < Rails::Engine
5
+ config.generators do |g|
6
+ g.test_framework :rspec, :fixture => false
7
+ g.fixture_replacement :factory_girl, :dir => 'spec/factories'
8
+ g.assets false
9
+ g.helper false
10
+ end
11
+
12
+ initializer "curupira.load_app_instance_data" do |app|
13
+ Curupira.setup do |config|
14
+ config.app_root = app.root
15
+ end
16
+ end
17
+
18
+ initializer "curupira.load_static_assets" do |app|
19
+ app.middleware.use ::ActionDispatch::Static, "#{root}/public"
20
+ end
21
+
22
+ initializer 'curupira.action_controller' do |app|
23
+ ActiveSupport.on_load :action_controller do
24
+ helper Curupira::RelationshipSelectOptionsHelper
25
+ include Curupira::Authorizer
26
+ helper_method :has_authorization_for
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,15 @@
1
+ module ActionDispatch::Routing
2
+ class Mapper
3
+ def curupira_routes
4
+ scope module: 'curupira' do
5
+ resources :users, except: :destroy
6
+ resources :groups, except: :destroy
7
+ resources :roles, except: :destroy
8
+ resource :session, only: [:new, :create] do
9
+ get :destroy, as: :destroy
10
+ end
11
+ resources :passwords, only: [:new, :create, :edit, :update]
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Curupira
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,27 @@
1
+ module Curupira
2
+ module Generators
3
+ class ControllersGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../" * 5, __FILE__)
5
+
6
+ def create_role_controller
7
+ controllers.each do |controller|
8
+ copy_file controller
9
+ end
10
+ end
11
+
12
+ def controllers
13
+ files_within_root('.', 'app/controllers/**/*.*')
14
+ end
15
+
16
+ private
17
+
18
+ def files_within_root(prefix, glob)
19
+ root = "#{self.class.source_root}/#{prefix}"
20
+
21
+ Dir["#{root}/#{glob}"].sort.map do |full_path|
22
+ full_path.sub(root, '.').gsub('/./', '/')
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,80 @@
1
+ require 'rails/generators/active_record'
2
+ require 'generators/curupira/install/model_generators_helper'
3
+
4
+ module Curupira
5
+ module Generators
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+ include Curupira::Generators::ModelGeneratorsHelper
9
+
10
+ source_root File.expand_path('../../templates', __FILE__)
11
+
12
+ def create_routes
13
+ invoke "curupira:routes"
14
+ end
15
+
16
+ def copy_initializer
17
+ copy_file 'sorcery.rb', 'config/initializers/sorcery.rb'
18
+ end
19
+
20
+ def create_role_group_user
21
+ create_model "role_group_user"
22
+ create_migration_to("role_group_user")
23
+ end
24
+
25
+ def create_authorization
26
+ create_model "authorization"
27
+ create_migration_to("authorization")
28
+ end
29
+
30
+ def create_feature
31
+ create_model "feature"
32
+ create_migration_to("feature")
33
+ end
34
+
35
+ def create_groups
36
+ create_model "group"
37
+ create_migration_to("group")
38
+ end
39
+
40
+ def create_role
41
+ create_model "role"
42
+ create_migration_to("role")
43
+ end
44
+
45
+ def create_user_model
46
+ create_model "user"
47
+ end
48
+
49
+ def create_user_migration
50
+ if table_exists?("user")
51
+ create_add_columns_migration_to("user")
52
+ else
53
+ copy_migration 'sorcery_core.rb'
54
+ end
55
+ end
56
+
57
+ def create_group_user
58
+ create_model "group_user"
59
+ create_migration_to("group_user")
60
+ end
61
+
62
+ def create_role_group
63
+ create_model "role_group"
64
+ create_migration_to("role_group")
65
+ end
66
+
67
+ def create_action_label
68
+ create_model "action_label"
69
+ create_migration_to("action_label")
70
+ end
71
+
72
+ private
73
+
74
+ def self.next_migration_number(dir)
75
+ ActiveRecord::Generators::Base.next_migration_number(dir)
76
+ end
77
+
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,266 @@
1
+ module Curupira
2
+ module Generators
3
+ module ModelGeneratorsHelper
4
+ include Rails::Generators::Migration
5
+
6
+ def table_exists?(table_name)
7
+ ActiveRecord::Base.connection.table_exists?(table_name)
8
+ end
9
+
10
+ def create_add_columns_migration_to(model_name)
11
+ if migration_needed?(model_name)
12
+ config = {
13
+ columns: columns_by(model_name),
14
+ indexes: indexes_by(model_name)
15
+ }
16
+
17
+ copy_migration("add_curupira_to_#{model_name.pluralize}.rb", config)
18
+ end
19
+ end
20
+
21
+ def copy_migration(migration_name, config = {})
22
+ unless migration_exists?(migration_name)
23
+ migration_template(
24
+ "db/migrate/#{migration_name}",
25
+ "db/migrate/#{migration_name}",
26
+ config
27
+ )
28
+ end
29
+ end
30
+
31
+ def create_migration_to(model_name)
32
+ if table_exists?(model_name)
33
+ create_add_columns_migration_to(model_name)
34
+ else
35
+ copy_migration "create_#{model_name.pluralize}.rb"
36
+ end
37
+ end
38
+
39
+ def migration_exists?(name)
40
+ existing_migrations.include?(name)
41
+ end
42
+
43
+ def existing_migrations
44
+ @existing_migrations ||= Dir.glob("db/migrate/*.rb").map do |file|
45
+ migration_name_without_timestamp(file)
46
+ end
47
+ end
48
+
49
+ def migration_name_without_timestamp(file)
50
+ file.sub(%r{^.*(db/migrate/)(?:\d+_)?}, '')
51
+ end
52
+
53
+ def migration_needed?(model_name)
54
+ columns_by(model_name).any? || indexes_by(model_name).any?
55
+ end
56
+
57
+ def user_columns
58
+ @user_columns ||= {
59
+ email: 't.string :email, null: false',
60
+ name: 't.string :name, null: false',
61
+ active: 't.boolean :active, null: false',
62
+ username: 't.string',
63
+ crypted_password: 't.string :crypted_password',
64
+ salt: 't.string :salt, default: nil',
65
+ reset_password_token: 't.string :reset_password_token, default: nil',
66
+ reset_password_token_expires_at: 't.datetime :reset_password_token_expires_at, default: nil',
67
+ reset_password_email_sent_at: 't.datetime :reset_password_email_sent_at, default: nil',
68
+ last_login_at: 't.datetime :last_login_at, default: nil',
69
+ last_logout_at: 't.datetime :last_logout_at, default: nil',
70
+ last_activity_at: 't.datetime :last_activity_at, default: nil',
71
+ last_login_from_ip_address: 't.string :last_login_from_ip_address, default: nil',
72
+ admin: 't.boolean :admin, default: false'
73
+ }.reject { |column| existing_columns_to("user").include?(column.to_s) }
74
+ end
75
+
76
+ def role_columns
77
+ @role_columns ||= {}
78
+ end
79
+
80
+ def role_indexes
81
+ @role_indexes ||= {}
82
+ end
83
+
84
+ def group_columns
85
+ @group_columns ||= {}
86
+ end
87
+
88
+ def group_indexes
89
+ @group_indexes ||= {}
90
+ end
91
+
92
+ def feature_columns
93
+ @feature_columns ||= {}
94
+ end
95
+
96
+ def feature_indexes
97
+ @feature_indexes ||= {}
98
+ end
99
+
100
+ def authorization_columns
101
+ @authorization_columns ||= {}
102
+ end
103
+
104
+ def authorization_indexes
105
+ @authorization_indexes ||= {}
106
+ end
107
+
108
+ def role_group_user_columns
109
+ @role_group_user_columns ||= {}
110
+ end
111
+
112
+ def role_group_user_indexes
113
+ @role_group_user_indexes ||= {}
114
+ end
115
+
116
+ def role_group_columns
117
+ @role_group_columns ||= {}
118
+ end
119
+
120
+ def role_group_indexes
121
+ @role_group_indexes ||= {}
122
+ end
123
+
124
+ def user_indexes
125
+ @user_indexes ||= {
126
+ index_users_on_username: 'add_index :users, :username, unique: true',
127
+ index_users_on_reset_password_token: 'add_index :users, :reset_password_token',
128
+ index_users_on_last_logout_at: 'add_index :users, :last_logout_at',
129
+ index_users_on_last_activity_at: 'add_index :users, :last_activity_at'
130
+ }.reject { |index| existing_indexes_to("user").include?(index.to_s) }
131
+ end
132
+
133
+ def group_user_columns
134
+ @group_user_columns ||= {}
135
+ end
136
+
137
+ def group_user_indexes
138
+ @group_user_indexes ||= {}
139
+ end
140
+
141
+ def action_label_columns
142
+ @action_label_columns ||= {}
143
+ end
144
+
145
+ def action_label_indexes
146
+ @action_label_indexes ||= {}
147
+ end
148
+
149
+ def create_model(model_name)
150
+ copy_file "models/#{model_name}.rb", "app/models/#{model_name}.rb" unless model_exists?("app/models/#{model_name}.rb")
151
+ content = self.send("#{model_name}_model_content").split("\n").map { |line| " " + line.strip! } .join("\n") << "\n"
152
+ inject_into_class("app/models/#{model_name}.rb", model_name.camelize, content)
153
+ end
154
+
155
+ def role_group_user_model_content
156
+ <<-CONTENT
157
+ belongs_to :group_user
158
+ belongs_to :role
159
+ CONTENT
160
+ end
161
+
162
+ def authorization_model_content
163
+ <<-CONTENT
164
+ belongs_to :feature
165
+ belongs_to :role
166
+ CONTENT
167
+ end
168
+
169
+ def user_model_content
170
+ <<-CONTENT
171
+ authenticates_with_sorcery!
172
+ validates_presence_of :email
173
+ has_many :group_users
174
+ has_many :groups, through: :group_users
175
+ has_many :role_group_users, through: :group_users
176
+ accepts_nested_attributes_for :group_users, reject_if: :all_blank, allow_destroy: :true
177
+
178
+ scope :all_belonging_to, -> (user) { includes(group_users: :group).where(groups: { id: user.groups }) }
179
+ CONTENT
180
+ end
181
+
182
+ def group_model_content
183
+ <<-CONTENT
184
+ has_many :role_groups
185
+ has_many :roles, through: :role_groups
186
+ has_many :group_users
187
+ has_many :users, through: :group_users
188
+ accepts_nested_attributes_for :role_groups, reject_if: :all_blank, allow_destroy: :true
189
+ validates_presence_of :name
190
+ scope :active, -> { where active: true }
191
+ CONTENT
192
+ end
193
+
194
+ def role_model_content
195
+ <<-CONTENT
196
+ has_many :authorizations
197
+ has_many :features, through: :authorizations
198
+ has_many :role_group_users
199
+ has_many :group_users, through: :role_group_users
200
+ has_many :role_groups
201
+ has_many :groups, through: :role_groups
202
+ accepts_nested_attributes_for :authorizations, reject_if: :all_blank, allow_destroy: :true
203
+ validates_presence_of :name
204
+ CONTENT
205
+ end
206
+
207
+ def feature_model_content
208
+ <<-CONTENT
209
+ validates_presence_of :name
210
+ has_many :feature_services
211
+ has_many :services, through: :feature_services
212
+ has_many :feature_action_labels
213
+ has_many :action_labels, through: :feature_action_labels
214
+ CONTENT
215
+ end
216
+
217
+ def group_user_model_content
218
+ <<-CONTENT
219
+ belongs_to :group
220
+ belongs_to :user
221
+ has_many :role_group_users
222
+ accepts_nested_attributes_for :role_group_users, reject_if: :all_blank, allow_destroy: :true
223
+ scope :active, -> { where active: true }
224
+ CONTENT
225
+ end
226
+
227
+ def role_group_model_content
228
+ <<-CONTENT
229
+ belongs_to :role
230
+ belongs_to :group
231
+ CONTENT
232
+ end
233
+
234
+ def action_label_model_content
235
+ <<-CONTENT
236
+ belongs_to :feature
237
+ CONTENT
238
+ end
239
+
240
+ def columns_by(model_name)
241
+ self.send("#{model_name}_columns")
242
+ end
243
+
244
+ def indexes_by(model_name)
245
+ self.send("#{model_name}_indexes")
246
+ end
247
+
248
+ def model_exists?(model_path)
249
+ File.exists?(File.join(destination_root, model_path))
250
+ end
251
+
252
+ def table_exists?(model_name)
253
+ ActiveRecord::Base.connection.table_exists?(model_name.pluralize.to_sym)
254
+ end
255
+
256
+ def existing_columns_to(model_name)
257
+ ActiveRecord::Base.connection.columns(model_name.pluralize.to_sym).map(&:name)
258
+ end
259
+
260
+ def existing_indexes_to(model_name)
261
+ ActiveRecord::Base.connection.indexes(model_name.pluralize.to_sym).map(&:name)
262
+ end
263
+
264
+ end
265
+ end
266
+ end