hydra-role-management 1.0.0 → 1.0.1

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