releaf-permissions 0.2.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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +24 -0
  3. data/app/assets/stylesheets/releaf/controllers/releaf/permissions/sessions.scss +70 -0
  4. data/app/builders/releaf/permissions/profile/form_builder.rb +7 -0
  5. data/app/builders/releaf/permissions/roles/form_builder.rb +28 -0
  6. data/app/builders/releaf/permissions/roles/table_builder.rb +16 -0
  7. data/app/builders/releaf/permissions/users/form_builder.rb +11 -0
  8. data/app/builders/releaf/permissions/users/table_builder.rb +11 -0
  9. data/app/controllers/releaf/permissions/home_controller.rb +32 -0
  10. data/app/controllers/releaf/permissions/profile_controller.rb +56 -0
  11. data/app/controllers/releaf/permissions/roles_controller.rb +7 -0
  12. data/app/controllers/releaf/permissions/sessions_controller.rb +34 -0
  13. data/app/controllers/releaf/permissions/users_controller.rb +19 -0
  14. data/app/lib/releaf/permissions/access_control.rb +36 -0
  15. data/app/models/releaf/permissions/permission.rb +6 -0
  16. data/app/models/releaf/permissions/role.rb +38 -0
  17. data/app/models/releaf/permissions/user.rb +31 -0
  18. data/app/views/releaf/permissions/sessions/new.html.haml +14 -0
  19. data/lib/releaf-permissions.rb +32 -0
  20. data/lib/releaf/permissions/builders_autoload.rb +11 -0
  21. data/lib/releaf/permissions/devise_component.rb +8 -0
  22. data/lib/releaf/permissions/engine.rb +24 -0
  23. data/lib/releaf/permissions/profile_component.rb +9 -0
  24. data/lib/releaf/permissions/roles_component.rb +7 -0
  25. data/lib/releaf/permissions/users_component.rb +7 -0
  26. data/releaf-permissions.gemspec +19 -0
  27. data/spec/builders/profile/form_builder_spec.rb +18 -0
  28. data/spec/builders/roles/form_builder_spec.rb +38 -0
  29. data/spec/builders/roles/table_builder_spec.rb +29 -0
  30. data/spec/builders/users/form_builder_spec.rb +23 -0
  31. data/spec/builders/users/table_builder_spec.rb +21 -0
  32. data/spec/controllers/permissions/home_controller_spec.rb +52 -0
  33. data/spec/controllers/permissions/profile_controller_spec.rb +66 -0
  34. data/spec/controllers/permissions/users_controller_spec.rb +28 -0
  35. data/spec/features/profile_updating_spec.rb +35 -0
  36. data/spec/features/roles_spec.rb +64 -0
  37. data/spec/features/users_spec.rb +107 -0
  38. data/spec/lib/access_control_spec.rb +81 -0
  39. data/spec/models/permissions/role_spec.rb +41 -0
  40. data/spec/models/permissions/user_spec.rb +23 -0
  41. metadata +124 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: caeca41a84ee2b226c802d750618fe9cc21741cd
4
+ data.tar.gz: dd7eab9ae5ebe9d558b5dd4fcddf665f0b4d2d52
5
+ SHA512:
6
+ metadata.gz: f3fffca96b935425d42c56750b716a4bf4df54529439474c18d0b3c33061903d2282e6c7df7c6ff27add308fe5ebb7009fc5998d957922f3a9273764f2b60109
7
+ data.tar.gz: eead458bca60cff29a335ccfa947aa13224557366b1a9cd155e36a3873ab8972b774a83df2b22dab857feb0f18be4ea540fb5b2457c6271dd19a959c84aba018
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2012, CubeSystems <info@cubesystems.lv>
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+ * Redistributions of source code must retain the above copyright
7
+ notice, this list of conditions and the following disclaimer.
8
+ * Redistributions in binary form must reproduce the above copyright
9
+ notice, this list of conditions and the following disclaimer in the
10
+ documentation and/or other materials provided with the distribution.
11
+ * Neither the name of the CubeSystems nor the names of its contributors may
12
+ be used to endorse or promote products derived from this software without
13
+ specific prior written permission.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL CubeSystems BE LIABLE FOR ANY
19
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,70 @@
1
+ @import 'releaf/environment';
2
+
3
+ .controller-releaf-permissions-sessions
4
+ {
5
+ @include inverted( $background-color: $color-background-inverted-darkest );
6
+
7
+ .container
8
+ {
9
+ position: absolute;
10
+ top: 0;
11
+ bottom: 0;
12
+ width: 100%;
13
+ height: 100%;
14
+
15
+ > .box
16
+ {
17
+ width: steps(26);
18
+ margin: 0 auto;
19
+ position: relative;
20
+ top: 15%;
21
+
22
+ .logo
23
+ {
24
+ width: steps(5);
25
+ height: steps(11);
26
+ background-repeat: no-repeat;
27
+ background-image: image-url("releaf/logo-login.png");
28
+ }
29
+
30
+ }
31
+
32
+ }
33
+
34
+ .field
35
+ {
36
+ margin-left: steps(1);
37
+ width: steps(24);
38
+
39
+ label
40
+ {
41
+ display: block;
42
+ }
43
+
44
+ .button
45
+ {
46
+ width: 100%;
47
+ }
48
+
49
+ input
50
+ {
51
+ font-weight: normal;
52
+ border: none;
53
+
54
+ }
55
+
56
+ .button
57
+ {
58
+ margin-top: steps(2);
59
+ background-color: $color-highlight-normal;
60
+ color: $color-text-inverted-lightest;
61
+
62
+ &:hover
63
+ {
64
+ background-color: $color-highlight-darker;
65
+ }
66
+ }
67
+
68
+ }
69
+
70
+ }
@@ -0,0 +1,7 @@
1
+ module Releaf::Permissions::Profile
2
+ class FormBuilder < Releaf::Permissions::Users::FormBuilder
3
+ def field_names
4
+ %w(name surname locale email password password_confirmation)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,28 @@
1
+ module Releaf::Permissions::Roles
2
+ class FormBuilder < Releaf::Builders::FormBuilder
3
+ def render_default_controller
4
+ controllers = {}
5
+ Releaf.application.config.available_controllers.each do |controller|
6
+ controllers[I18n.t(controller, scope: 'admin.controllers')] = controller
7
+ end
8
+
9
+ releaf_item_field(:default_controller, options: {select_options: controllers})
10
+ end
11
+
12
+ def render_permissions
13
+ options = {
14
+ items: permission_items,
15
+ field: :permission,
16
+ }
17
+ releaf_associated_set_field(:permissions, options: {association: options})
18
+ end
19
+
20
+ def permission_items
21
+ list = {}
22
+ Releaf.application.config.available_controllers.each do|controller|
23
+ list["controller.#{controller}"] = t(controller, scope: "admin.controllers")
24
+ end
25
+ list
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,16 @@
1
+ module Releaf::Permissions::Roles
2
+ class TableBuilder < Releaf::Builders::TableBuilder
3
+ def column_names
4
+ [:name, :default_controller]
5
+ end
6
+
7
+ def default_controller_content(resource)
8
+ value = resource.default_controller
9
+ if value.nil?
10
+ '-'
11
+ else
12
+ I18n.t(value.sub('_', '/'), scope: 'admin.controllers')
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Releaf::Permissions::Users
2
+ class FormBuilder < Releaf::Builders::FormBuilder
3
+ def field_names
4
+ %w(name surname locale role_id email password password_confirmation)
5
+ end
6
+
7
+ def render_locale
8
+ releaf_item_field(:locale, options: {select_options: locale_options(Releaf.application.config.available_admin_locales)})
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ module Releaf::Permissions::Users
2
+ class TableBuilder < Releaf::Builders::TableBuilder
3
+ def column_names
4
+ [:name, :surname, :role, :email, :locale]
5
+ end
6
+
7
+ def locale_content(resource)
8
+ translate_locale(resource.locale)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ module Releaf::Permissions
2
+ class HomeController < Releaf::BaseController
3
+ def home
4
+ respond_to do |format|
5
+ format.html { redirect_to default_or_available_controller_path }
6
+ end
7
+ end
8
+ protected
9
+
10
+ def default_or_available_controller_path
11
+ controllers_to_try.each do |controller_string|
12
+ begin
13
+ return url_for(action: 'index', controller: "/#{controller_string}")
14
+ rescue ActionController::UrlGenerationError
15
+ next
16
+ end
17
+ end
18
+
19
+ root_path
20
+ end
21
+
22
+ def controllers_to_try
23
+ [access_control.user.role.default_controller, allowed_controllers].flatten.uniq
24
+ end
25
+
26
+ def allowed_controllers
27
+ # Note: This basically sorts allowed controllers in order specified by
28
+ # Releaf.application.config.available_controllers
29
+ Releaf.application.config.available_controllers & access_control.user.role.allowed_controllers
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,56 @@
1
+ module Releaf::Permissions
2
+ class ProfileController < Releaf::BaseController
3
+ # Store settings for menu collapsing and others
4
+ def settings
5
+ if params[:settings].is_a? Hash
6
+ params[:settings].each_pair do|key, value|
7
+ value = false if value == "false"
8
+ value = true if value == "true"
9
+ # Sometimes concurrency happens, so lets try until
10
+ # record get updated
11
+ begin
12
+ @resource.settings[key] = value
13
+ rescue ActiveRecord::RecordNotUnique
14
+ retry
15
+ end
16
+ end
17
+ render nothing: true, status: 200
18
+ else
19
+ render nothing: true, status: 422
20
+ end
21
+ end
22
+
23
+ def success_url
24
+ url_for(action: :edit)
25
+ end
26
+
27
+ def update
28
+ old_password = @resource.password
29
+ super
30
+
31
+ # reload resource as password has been changed
32
+ if @resource.password != old_password
33
+ sign_in(access_control.user, bypass: true)
34
+ end
35
+ end
36
+
37
+ def self.resource_class
38
+ Releaf.application.config.devise_for.classify.constantize
39
+ end
40
+
41
+ def controller_breadcrumb; end
42
+
43
+ def setup
44
+ @features = {
45
+ edit: true,
46
+ }
47
+
48
+ # use already loaded admin user instance
49
+ @resource = access_control.user.becomes(resource_class)
50
+ end
51
+
52
+ def permitted_params
53
+ %w[name surname email password password_confirmation locale]
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,7 @@
1
+ module Releaf::Permissions
2
+ class RolesController < Releaf::BaseController
3
+ def self.resource_class
4
+ Releaf::Permissions::Role
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ module Releaf::Permissions
2
+ class SessionsController < Devise::SessionsController
3
+ layout "releaf/admin"
4
+ helper_method :page_title
5
+
6
+ def page_title
7
+ Rails.application.class.parent_name
8
+ end
9
+
10
+ def access_control
11
+ @access_control ||= Releaf::Permissions::AccessControl.new(controller: self)
12
+ end
13
+
14
+ def layout_settings(key)
15
+ access_control.user.try(:settings).try(:[], 'releaf.side.compact')
16
+ end
17
+
18
+ protected
19
+
20
+ def after_sign_in_path_for resource
21
+ if custom_redirect_path
22
+ custom_redirect_path
23
+ else
24
+ stored_location_for(resource) || releaf_root_path
25
+ end
26
+ end
27
+
28
+ def custom_redirect_path
29
+ return nil if params[:redirect_to].blank?
30
+ return nil if params[:redirect_to][0] != '/'
31
+ return params[:redirect_to]
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ module Releaf::Permissions
2
+ class UsersController < Releaf::BaseController
3
+
4
+ def self.resource_class
5
+ Releaf::Permissions::User
6
+ end
7
+
8
+ protected
9
+
10
+ def prepare_new
11
+ super
12
+ @resource.role = Releaf::Permissions::Role.first
13
+ end
14
+
15
+ def permitted_params
16
+ %w[name surname role_id email password password_confirmation locale]
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,36 @@
1
+ module Releaf::Permissions
2
+ class AccessControl
3
+ include ActiveModel::Model
4
+ attr_accessor :controller
5
+
6
+ def controller_permitted?(controller_name)
7
+ permitted_controllers.include?(controller_name) || user.role.controller_permitted?(controller_name)
8
+ end
9
+
10
+ def current_controller_name
11
+ controller.class.name.gsub("Controller", "").underscore
12
+ end
13
+
14
+ def user
15
+ controller.send("current_#{devise_model_name}")
16
+ end
17
+
18
+ def permitted_controllers
19
+ ['releaf/permissions/home', 'releaf/core/errors']
20
+ end
21
+
22
+ def authorized?
23
+ method_name = "#{devise_model_name}_signed_in?"
24
+ controller.send(method_name)
25
+ end
26
+
27
+ def authenticate!
28
+ method_name = "authenticate_#{devise_model_name}!"
29
+ controller.send(method_name)
30
+ end
31
+
32
+ def devise_model_name
33
+ Releaf.application.config.devise_for.underscore.tr('/', '_')
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,6 @@
1
+ module Releaf::Permissions
2
+ class Permission < ActiveRecord::Base
3
+ self.table_name = 'releaf_permissions'
4
+ belongs_to :owner, polymorphic: true, autosave: false
5
+ end
6
+ end
@@ -0,0 +1,38 @@
1
+ module Releaf::Permissions
2
+ class Role < ActiveRecord::Base
3
+ self.table_name = 'releaf_roles'
4
+
5
+ validates_presence_of :name
6
+ validates_presence_of :default_controller
7
+ validates_uniqueness_of :name, case_sensitive: false
8
+
9
+ has_many :users, dependent: :restrict_with_exception
10
+ has_many :permissions, as: :owner, class_name: "Releaf::Permissions::Permission", dependent: :destroy
11
+ accepts_nested_attributes_for :permissions, allow_destroy: true
12
+
13
+ alias_attribute :to_text, :name
14
+
15
+ # Check whether given controller name is within roles allowed controller list
16
+ #
17
+ # @param controller_name [String] controller name to check permissions against (ex. products)
18
+ # @return [true, false] whether controller is permitted for role
19
+ def controller_permitted?(controller_name)
20
+ allowed_controllers.include?(controller_name)
21
+ end
22
+
23
+ # Load all permissions and build list with allowed controler.
24
+ # In this way permissions are cached resulting only single db hit per multiple permissions checks.
25
+ #
26
+ # @return [Array] array of allowed controller names
27
+ def allowed_controllers
28
+ permissions.map{|permission| self.class.controller_name_from_permission(permission) }.compact
29
+ end
30
+
31
+ private
32
+
33
+ def self.controller_name_from_permission(permission)
34
+ match = permission.permission.match(/^controller\.(.+)/)
35
+ match[1] if match
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,31 @@
1
+ module Releaf::Permissions
2
+ class User < ActiveRecord::Base
3
+ self.table_name = 'releaf_users'
4
+
5
+ # store UI settings with RailsSettings
6
+ include RailsSettings::Extend
7
+
8
+ # Include default devise modules. Others available are:
9
+ # :token_authenticatable, :confirmable,
10
+ # :lockable, :timeoutable and :omniauthable
11
+ # :registerable
12
+ devise :database_authenticatable, :rememberable, :trackable, :validatable
13
+ validates_presence_of :name, :surname, :role, :locale
14
+
15
+ belongs_to :role
16
+
17
+ # Concatenate name and surname for object displaying
18
+ def display_name
19
+ [self.name, self.surname].join(' ')
20
+ end
21
+ alias :to_text :display_name
22
+
23
+ protected
24
+
25
+ # Require password if we have new record or instance have empty password
26
+ def password_required?
27
+ self.new_record? || self.encrypted_password.blank?
28
+ end
29
+
30
+ end
31
+ end