hydra-role-management 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +68 -0
  3. data/.rubocop.yml +50 -0
  4. data/CONTRIBUTING.md +22 -20
  5. data/Gemfile +3 -3
  6. data/README.md +33 -1
  7. data/Rakefile +14 -17
  8. data/SUPPORT.md +6 -0
  9. data/app/controllers/concerns/hydra/role_management/roles_behavior.rb +15 -16
  10. data/app/controllers/concerns/hydra/role_management/user_roles_behavior.rb +9 -8
  11. data/app/controllers/roles_controller.rb +2 -1
  12. data/app/controllers/user_roles_controller.rb +2 -2
  13. data/app/models/concerns/hydra/role_management/legacy_attribute_handling.rb +2 -0
  14. data/app/models/concerns/hydra/role_management/user_roles.rb +5 -4
  15. data/app/models/role.rb +8 -5
  16. data/app/views/roles/edit.html.erb +1 -1
  17. data/config/routes.rb +2 -2
  18. data/hydra-role-management.gemspec +19 -14
  19. data/lib/generators/roles/roles_generator.rb +30 -32
  20. data/lib/generators/roles/templates/hydra_role_management_rails3.rb +2 -1
  21. data/lib/generators/roles/templates/migrations/user_roles.rb +3 -2
  22. data/lib/hydra-role-management.rb +9 -3
  23. data/lib/hydra/role_management.rb +4 -2
  24. data/lib/hydra/role_management/version.rb +2 -1
  25. data/spec/controllers/roles_controller_spec.rb +27 -30
  26. data/spec/controllers/user_roles_controller_spec.rb +15 -13
  27. data/spec/lib/user_roles_spec.rb +21 -21
  28. data/spec/models/role_spec.rb +22 -20
  29. data/spec/routing/role_management_routes_spec.rb +29 -44
  30. data/spec/spec_helper.rb +4 -2
  31. data/spec/test_app_templates/app/models/sample.rb +7 -8
  32. data/spec/test_app_templates/app/models/solr_document.rb +2 -2
  33. data/spec/test_app_templates/config/initializers/hydra_config.rb +6 -6
  34. data/spec/test_app_templates/lib/generators/test_app_generator.rb +6 -5
  35. metadata +88 -17
  36. data/.travis.yml +0 -11
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
2
+ # Controller for managing Roles
1
3
  class RolesController < ApplicationController
2
4
  include Hydra::RoleManagement::RolesBehavior
3
5
  end
4
-
@@ -1,5 +1,5 @@
1
+ # frozen_string_literal: true
2
+ # Controller for managing Roles for Users
1
3
  class UserRolesController < ApplicationController
2
4
  include Hydra::RoleManagement::UserRolesBehavior
3
5
  end
4
-
5
-
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  module Hydra
2
3
  module RoleManagement
4
+ # Module for ensuring compatibility with Rails releases earlier than 4.0
3
5
  module LegacyAttributeHandling
4
6
  extend ActiveSupport::Concern
5
7
  included do
@@ -1,30 +1,31 @@
1
+ # frozen_string_literal: true
1
2
  module Hydra
2
3
  module RoleManagement
4
+ # Module offering methods for user behavior managing roles and groups
3
5
  module UserRoles
4
6
  extend ActiveSupport::Concern
7
+
5
8
  included do
6
9
  has_and_belongs_to_many :roles
7
10
  end
8
11
 
9
12
  def groups
10
13
  g = roles.map(&:name)
11
- g += ['registered'] unless new_record? || guest?
14
+ g += ['registered'] unless new_record? || guest?
12
15
  g
13
16
  end
14
17
 
15
18
  def guest?
16
19
  if defined?(DeviseGuests)
17
- read_attribute :guest
20
+ self[:guest]
18
21
  else
19
22
  false
20
23
  end
21
24
  end
22
-
23
25
 
24
26
  def admin?
25
27
  roles.where(name: 'admin').exists?
26
28
  end
27
-
28
29
  end
29
30
  end
30
31
  end
data/app/models/role.rb CHANGED
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+ # Class modeling Roles within the application
1
3
  class Role < ActiveRecord::Base
2
4
  has_and_belongs_to_many :users
3
5
 
4
- validates :name,
5
- uniqueness: true,
6
- format: { with: /\A[a-zA-Z0-9._-]+\z/,
7
- :message => "Only letters, numbers, hyphens, underscores and periods are allowed"}
8
-
6
+ validates :name,
7
+ uniqueness: true,
8
+ format: {
9
+ with: /\A[a-zA-Z0-9._-]+\z/,
10
+ message: 'Only letters, numbers, hyphens, underscores and periods are allowed'
11
+ }
9
12
  end
@@ -13,7 +13,7 @@
13
13
  <% @role.users.each do |user| %>
14
14
  <li><%= user.user_key %>
15
15
  <% if can? :remove_user, Role %>
16
- <%= button_to t('role-management.edit.remove'), role_management.role_user_path(@role, user), :method=>:delete, :class=>'btn btn-danger' %>
16
+ <%= button_to t('role-management.edit.remove'), role_management.role_user_path(@role, user.id), :method=>:delete, :class=>'btn btn-danger' %>
17
17
  <% end %>
18
18
  </li>
19
19
  <% end %>
data/config/routes.rb CHANGED
@@ -1,7 +1,7 @@
1
+ # frozen_string_literal: true
1
2
  Hydra::RoleManagement::Engine.routes.draw do
2
3
  # Generic file routes
3
4
  resources :roles, Hydra::RoleManagement.route_options do
4
- resources :users, :only=>[:create, :destroy], :controller => "user_roles"
5
+ resources :users, only: [:create, :destroy], controller: "user_roles"
5
6
  end
6
7
  end
7
-
@@ -1,27 +1,32 @@
1
- # -*- encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
2
  require File.expand_path('../lib/hydra/role_management/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ["Justin Coyne"]
6
- gem.email = ["justin@curationexperts.com"]
7
- gem.description = %q{Rails engine to do user roles in an RDBMS for hydra-head}
8
- gem.summary = %q{Rails engine to do user roles in an RDBMS for hydra-head}
9
- gem.homepage = "https://github.com/samvera/hydra-role-management"
5
+ gem.authors = ['Justin Coyne']
6
+ gem.email = ['justin@curationexperts.com']
7
+ gem.description = 'Rails engine to do user roles in an RDBMS for hydra-head'
8
+ gem.summary = 'Rails engine to do user roles in an RDBMS for hydra-head'
9
+ gem.homepage = 'https://github.com/samvera/hydra-role-management'
10
10
 
11
- gem.files = `git ls-files`.split($\)
12
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
11
+ gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
13
13
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
- gem.name = "hydra-role-management"
15
- gem.require_paths = ["lib"]
14
+ gem.name = 'hydra-role-management'
15
+ gem.require_paths = ['lib']
16
16
  gem.version = Hydra::RoleManagement::VERSION
17
17
  gem.license = 'Apache 2.0'
18
18
 
19
- gem.add_dependency 'bootstrap_form'
20
19
  gem.add_dependency 'blacklight'
20
+ gem.add_dependency 'bootstrap_form'
21
+ gem.add_dependency 'bundler', '>= 1.5'
21
22
  gem.add_dependency 'cancancan'
23
+ gem.add_dependency 'json', '~> 1.8'
24
+ gem.add_development_dependency 'bixby', '~> 1.0.0'
25
+ gem.add_development_dependency 'engine_cart', '~> 2.1'
26
+ gem.add_development_dependency 'pry-byebug'
27
+ gem.add_development_dependency 'rails-controller-testing', '~> 0'
22
28
  gem.add_development_dependency 'rake'
23
- gem.add_development_dependency 'rspec-rails'
24
29
  gem.add_development_dependency 'rspec-its'
25
- gem.add_development_dependency 'rails-controller-testing', '~> 0'
26
- gem.add_development_dependency 'engine_cart', '~> 1.0'
30
+ gem.add_development_dependency 'rspec-rails'
31
+ gem.add_development_dependency 'rspec_junit_formatter'
27
32
  end
@@ -1,27 +1,29 @@
1
- # -*- encoding : utf-8 -*-
1
+
2
+ # frozen_string_literal: true
2
3
  require 'rails/generators'
3
4
  require 'rails/generators/migration'
4
5
 
6
+ # Class definition for the Rails Generator integrating Roles
5
7
  class RolesGenerator < Rails::Generators::Base
6
8
  include Rails::Generators::Migration
7
9
 
8
10
  source_root File.expand_path('../templates', __FILE__)
9
11
 
10
- argument :model_name, :type => :string , :default => "user"
11
- desc """
12
+ argument :model_name, type: :string, default: 'user'
13
+ desc '
12
14
  This generator makes the following changes to your application:
13
15
  1. Creates several database migrations if they do not exist in /db/migrate
14
16
  2. Adds user behavior to the user model
15
17
  2. Adds routes
16
- """
18
+ '
17
19
 
18
20
  # Implement the required interface for Rails::Generators::Migration.
19
21
  # taken from http://github.com/rails/rails/blob/master/activerecord/lib/generators/active_record.rb
20
- def self.next_migration_number(path)
21
- unless @prev_migration_nr
22
- @prev_migration_nr = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i
23
- else
22
+ def self.next_migration_number(_path)
23
+ if @prev_migration_nr
24
24
  @prev_migration_nr += 1
25
+ else
26
+ @prev_migration_nr = Time.now.utc.strftime('%Y%m%d%H%M%S').to_i
25
27
  end
26
28
  @prev_migration_nr.to_s
27
29
  end
@@ -29,7 +31,7 @@ This generator makes the following changes to your application:
29
31
  # Setup the database migrations
30
32
  def copy_migrations
31
33
  # Can't get this any more DRY, because we need this order.
32
- %w{user_roles.rb}.each do |f|
34
+ %w[user_roles.rb].each do |f|
33
35
  better_migration_template f
34
36
  end
35
37
  end
@@ -37,49 +39,45 @@ This generator makes the following changes to your application:
37
39
  # Add behaviors to the user model
38
40
  def inject_user_roles_behavior
39
41
  file_path = "app/models/#{model_name.underscore}.rb"
40
- if File.exists?(file_path)
41
- place_marker = if File.read(file_path).match(/include Hydra::User/)
42
- /include Hydra::User/
43
- elsif File.read(file_path).match(/include Blacklight::User/)
44
- /include Blacklight::User/
45
- end
42
+ if File.exist?(file_path)
43
+ place_marker = if File.read(file_path).match?(/include Hydra::User/)
44
+ /include Hydra::User/
45
+ elsif File.read(file_path).match?(/include Blacklight::User/)
46
+ /include Blacklight::User/
47
+ end
46
48
  if place_marker
47
- code = "\n # Connects this user object to Role-management behaviors.\n" +
48
- " include Hydra::RoleManagement::UserRoles\n\n"
49
- inject_into_file file_path, code, { :after => place_marker }
49
+ code = "\n # Connects this user object to Role-management behaviors.\n" \
50
+ " include Hydra::RoleManagement::UserRoles\n\n"
51
+ inject_into_file file_path, code, after: place_marker
50
52
  else
51
- puts " \e[31mFailure\e[0m Hydra::User is not included in #{file_path}. Add 'include Hydra::User' and rerun."
53
+ Rails.logger.error " \e[31mFailure\e[0m Hydra::User is not included in #{file_path}. Add 'include Hydra::User' and rerun."
52
54
  end
53
55
  else
54
- puts " \e[31mFailure\e[0m hydra-role-management requires a user object. This generators assumes that the model is defined in the file #{file_path}, which does not exist. If you used a different name, please re-run the generator and provide that name as an argument. Such as \b rails -g roles client"
56
+ Rails.logger.error " \e[31mFailure\e[0m hydra-role-management requires a user object. This generators assumes that the model is defined in the file #{file_path}, which does not exist. If you used a different name, please re-run the generator and provide that name as an argument. Such as \b rails -g roles client"
55
57
  end
56
58
  end
57
59
 
58
60
  # The engine routes have to come after the devise routes so that /users/sign_in will work
59
61
  def inject_routes
60
62
  routing_code = "mount Hydra::RoleManagement::Engine => '/'"
61
- sentinel = /devise_for :users/
62
- inject_into_file 'config/routes.rb', "\n #{routing_code}\n", { :after => sentinel, :verbose => false }
63
+ sentinel = /devise_for :users(.*)$/
64
+ inject_into_file 'config/routes.rb', "\n #{routing_code}\n", after: sentinel, verbose: false
63
65
  end
64
66
 
65
67
  # If this gem is installed under Rails 3, an attr_accessible method is required for the Role model. This
66
68
  # file will be added to config/initializers and the correct code will be added to the model at runtime.
67
69
  def rails3_attr_accessible
68
- if !ActionController.const_defined? :StrongParameters
69
- puts "Role model will include attr_accessible :name because you are installing this gem in a Rails 3 app."
70
- copy_file "hydra_role_management_rails3.rb", "config/initializers/hydra_role_management_rails3.rb"
71
- end
70
+ return if ActionController.const_defined? :StrongParameters
71
+ Rails.logger.info 'Role model will include attr_accessible :name because you are installing this gem in a Rails 3 app.'
72
+ copy_file 'hydra_role_management_rails3.rb', 'config/initializers/hydra_role_management_rails3.rb'
72
73
  end
73
74
 
74
75
  private
75
76
 
76
- def better_migration_template (file)
77
- begin
77
+ def better_migration_template(file)
78
78
  sleep 1 # ensure scripts have different time stamps
79
79
  migration_template "migrations/#{file}", "db/migrate/#{file}"
80
- rescue
81
- puts " \e[1m\e[34mMigrations\e[0m " + $!.message
80
+ rescue StandardError
81
+ Rails.logger.error " \e[1m\e[34mMigrations\e[0m " + $ERROR_INFO.message
82
82
  end
83
- end
84
-
85
83
  end
@@ -1 +1,2 @@
1
- Role.send :include, Hydra::RoleManagement::LegacyAttributeHandling
1
+ # frozen_string_literal: true
2
+ Role.send :include, Hydra::RoleManagement::LegacyAttributeHandling
@@ -1,9 +1,10 @@
1
- class UserRoles < ActiveRecord::Migration<%= '[5.0]' if Rails::VERSION::MAJOR >= 5 %>
1
+ # frozen_string_literal: true
2
+ class UserRoles < ActiveRecord::Migration[5.0]
2
3
  def up
3
4
  create_table :roles do |t|
4
5
  t.string :name
5
6
  end
6
- create_table :roles_users, :id => false do |t|
7
+ create_table :roles_users, id: false do |t|
7
8
  t.references :role
8
9
  t.references :user
9
10
  end
@@ -1,12 +1,18 @@
1
- require "hydra/role_management"
1
+ # frozen_string_literal: true
2
+ require 'hydra/role_management'
2
3
  require 'bootstrap_form'
3
4
 
4
5
  module Hydra
5
6
  module RoleManagement
6
7
  mattr_accessor :route_options
7
8
  self.route_options = {}
8
-
9
- def self.draw_routes(router, opts={})
9
+
10
+ # Draws the routes with custom arguments passed to the #mount invocation
11
+ # @param router [ActionDispatch::Routing::Mapper] the Rails routing mapper
12
+ # @param opts [Hash] the argument passed to ActionDispatch::Routing::Mapper#mount
13
+ # @see http://api.rubyonrails.org/classes/ActionDispatch/Routing/Mapper/Base.html
14
+ # (see ActionDispatch::Routing::Mapper::Base)
15
+ def self.draw_routes(router, opts = {})
10
16
  self.route_options = opts
11
17
  router.instance_exec do
12
18
  mount Hydra::RoleManagement::Engine => '/'
@@ -1,12 +1,14 @@
1
+ # frozen_string_literal: true
1
2
  require 'cancan'
2
3
  module Hydra
3
4
  module RoleManagement
5
+ # Class definition for the Rails Engine
4
6
  class Engine < ::Rails::Engine
5
7
  engine_name 'role_management'
6
8
 
7
9
  # Rails 4 should do this automatically:
8
- config.paths.add "app/controllers/concerns", eager_load: true
9
- config.paths.add "app/models/concerns", eager_load: true
10
+ config.paths.add 'app/controllers/concerns', eager_load: true
11
+ config.paths.add 'app/models/concerns', eager_load: true
10
12
  end
11
13
  end
12
14
  end
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
  module Hydra
2
3
  module RoleManagement
3
- VERSION = "1.0.0"
4
+ VERSION = '1.0.1'
4
5
  end
5
6
  end
@@ -1,51 +1,48 @@
1
+ # frozen_string_literal: true
1
2
  describe RolesController do
3
+ routes { Hydra::RoleManagement::Engine.routes }
2
4
  let(:ability) do
3
5
  ability = Object.new
4
6
  ability.extend(CanCan::Ability)
5
7
  allow(controller).to receive(:current_ability).and_return(ability)
6
8
  ability
7
9
  end
8
-
9
10
  let(:role) do
10
11
  Role.create(name: 'foo')
11
12
  end
12
13
 
13
- before(:each) do
14
- @routes = Hydra::RoleManagement::Engine.routes
15
- end
16
-
17
- describe "with a user who cannot edit roles" do
18
- it "should not be able to view role index" do
14
+ describe 'with a user who cannot edit roles' do
15
+ it 'is not able to view role index' do
19
16
  expect { get :index, params: {} }.to raise_error CanCan::AccessDenied
20
17
  end
21
- it "should not be able to view role" do
18
+ it 'is not able to view role' do
22
19
  expect { get :show, params: { id: role } }.to raise_error CanCan::AccessDenied
23
20
  end
24
- it "should not be able to view new role form" do
21
+ it 'is not able to view new role form' do
25
22
  expect { get :new }.to raise_error CanCan::AccessDenied
26
23
  end
27
- it "should not be able to create a role" do
24
+ it 'is not able to create a role' do
28
25
  expect { post :create, params: { role: { name: 'my_role' } } }.to raise_error CanCan::AccessDenied
29
26
  end
30
- it "should not be able to update a role" do
27
+ it 'is not able to update a role' do
31
28
  expect { put :update, params: { id: role } }.to raise_error CanCan::AccessDenied
32
29
  end
33
- it "should not be able to remove a role" do
30
+ it 'is not able to remove a role' do
34
31
  expect { delete :destroy, params: { id: role } }.to raise_error CanCan::AccessDenied
35
32
  end
36
33
  end
37
34
 
38
- describe "with a user who can read roles" do
35
+ describe 'with a user who can read roles' do
39
36
  before do
40
37
  ability.can :read, Role
41
38
  end
42
- it "should be able to see the list of roles" do
39
+ it 'is able to see the list of roles' do
43
40
  get :index
44
41
  expect(response).to be_successful
45
42
  expect(assigns[:roles]).to eq [role]
46
43
  end
47
44
 
48
- it "should be able to see a single role" do
45
+ it 'is able to see a single role' do
49
46
  get :show, params: { id: role }
50
47
  expect(response).to be_successful
51
48
  expect(assigns[:role]).to eq role
@@ -53,31 +50,31 @@ describe RolesController do
53
50
  end
54
51
 
55
52
  describe "with a user who can only update role 'foo'" do
56
- it "should be redirected to edit" do
53
+ it 'is redirected to edit' do
57
54
  ability.can :read, Role
58
55
  ability.can :update, Role, id: role.id
59
56
  get :show, params: { id: role }
60
- expect(response).to redirect_to @routes.url_helpers.edit_role_path(assigns[:role])
57
+ expect(response).to redirect_to routes.url_helpers.edit_role_path(assigns[:role])
61
58
  end
62
59
  end
63
60
 
64
- describe "with a user who can create roles" do
61
+ describe 'with a user who can create roles' do
65
62
  before do
66
63
  ability.can :create, Role
67
64
  end
68
- it "should be able to make a new role" do
65
+ it 'is able to make a new role' do
69
66
  get :new
70
67
  expect(response).to be_successful
71
68
  expect(assigns[:role]).to be_kind_of Role
72
69
  end
73
70
 
74
- it "should be able to create a new role" do
71
+ it 'is able to create a new role' do
75
72
  post :create, params: { role: { name: 'my_role' } }
76
- expect(response).to redirect_to @routes.url_helpers.edit_role_path(assigns[:role])
73
+ expect(response).to redirect_to routes.url_helpers.edit_role_path(assigns[:role])
77
74
  expect(assigns[:role]).not_to be_new_record
78
75
  expect(assigns[:role].name).to eq 'my_role'
79
76
  end
80
- it "should not create role with an error" do
77
+ it 'does not create role with an error' do
81
78
  post :create, params: { role: { name: 'my role' } }
82
79
  expect(assigns[:role].name).to eq 'my role'
83
80
  expect(assigns[:role].errors[:name]).to eq ['Only letters, numbers, hyphens, underscores and periods are allowed']
@@ -85,33 +82,33 @@ describe RolesController do
85
82
  end
86
83
  end
87
84
 
88
- describe "with a user who can update roles" do
85
+ describe 'with a user who can update roles' do
89
86
  before do
90
87
  ability.can :update, Role
91
88
  end
92
89
 
93
- it "should be able to update a role" do
90
+ it 'is able to update a role' do
94
91
  put :update, params: { id: role, role: { name: 'my_role' } }
95
- expect(response).to redirect_to @routes.url_helpers.edit_role_path(assigns[:role])
92
+ expect(response).to redirect_to routes.url_helpers.edit_role_path(assigns[:role])
96
93
  expect(assigns[:role]).not_to be_new_record
97
94
  expect(assigns[:role].name).to eq 'my_role'
98
95
  end
99
- it "should not update role with an error" do
100
- put :update, params: { id: role, role: { name: 'my role' } }
96
+ it 'does not update role with an error' do
97
+ put :update, params: { id: role, role: { name: 'my role' } }
101
98
  expect(assigns[:role].name).to eq 'my role'
102
99
  expect(assigns[:role].errors[:name]).to eq ['Only letters, numbers, hyphens, underscores and periods are allowed']
103
100
  expect(response).to be_successful
104
101
  end
105
102
  end
106
103
 
107
- describe "with a user who can remove roles" do
104
+ describe 'with a user who can remove roles' do
108
105
  before do
109
106
  ability.can :destroy, Role
110
107
  end
111
108
 
112
- it "should be able to destroy a role" do
109
+ it 'is able to destroy a role' do
113
110
  delete :destroy, params: { id: role }
114
- expect(response).to redirect_to @routes.url_helpers.roles_path
111
+ expect(response).to redirect_to routes.url_helpers.roles_path
115
112
  end
116
113
  end
117
114
  end