dynamican 0.1.7 → 0.1.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d6dd7da02224c7b3e20e8b582f5929657255d33d4ddf81037a09e2c303df7182
4
- data.tar.gz: 1c7f34c8b6335a89c21087243bdcaec746966ff76c7bc076204aefa736fce121
3
+ metadata.gz: 2919c67cd907ca110db119ff27da8eb0ab7dc7fef6d9911de9b2ed04fdd111e2
4
+ data.tar.gz: 3e89dcbe20185469f70b2d066264f848be3c8ef92b0f9e18771a9b6bc23d69a3
5
5
  SHA512:
6
- metadata.gz: ea646968f0358bada82722bda78c2895bd6763428823f02ab51866caedbd45e7af0f411b5e77850e2bb71f83751503922aed96cb39b906fd344ebcca453154d9
7
- data.tar.gz: 3c29cc459e4aff80101d2ec436deba04c3600410e030cc4e3cf09ad575df8b3cd1f93602a8639937930733c82513a6ea8293eeddbb309cd9cb5afe7159bfd329
6
+ metadata.gz: f97e9268851d07d730e2d4cada589ed6c35ae57f8d127854d4199cd93b464dd1de342c6b9e674434be535a09ca9be8a52ad811d0fde348c846148b0c62494c3e
7
+ data.tar.gz: 35b2f9fe8360a9cbd4e9627b9a4249ee6aca206d6a394f2a8909ea8b74e53605eb64cc04119d1c11ad0d871a06d85313c81d2e89c1faa6bba2d17b79714a0411
data/README.md CHANGED
@@ -1,20 +1,18 @@
1
1
  # Dynamican
2
- Dynamican is a flexible gem to introduce permissions on rails applications. It is very customizable because it stores all the rules inside the database and can be added to multiple models: for example you can add permissions to your Role model or to users. With a couple of overrides you can also add permissions to both Role and User and use role permissions through user.
2
+ Dynamican is a flexible gem which introduces permissions on rails applications. It is very customizable because it stores all the rules inside the database and can be added to multiple models: for example you can add permissions to your Role and User models. With a couple of overrides you can also add permissions to both Role and User and allow user to use its roles permissions.
3
3
 
4
4
  ## Installation
5
5
  Inside your Gemfile put
6
6
 
7
7
  gem 'dynamican'
8
8
 
9
- then run `bundle install`
9
+ and then run `bundle install`
10
10
 
11
- Once you have the gem, open the source code and look for migrations folder. You need to create in your project those migrations and run them. Obviously if you already have the gem installed and you are only updating, you only need to create the migrations for the later versions of the gem.
12
-
13
- In each model you want to have the feature, just put
11
+ In each model you want to have the feature, just put the following.
14
12
 
15
13
  include Dynamican::Model
16
14
 
17
- Create `config/dynamican.yml` file and compile it as follows for each of the models you included the code above into (let's say for instance you included Dynamican::Model into User and Role models)
15
+ Create `config/dynamican.yml` file in your project and compile it as follows for each of the models you included the code above into (let's say for instance you included Dynamican::Model into User and Role models).
18
16
 
19
17
  associations:
20
18
  role:
@@ -22,9 +20,15 @@ Create `config/dynamican.yml` file and compile it as follows for each of the mod
22
20
  user:
23
21
  class_name: 'User'
24
22
 
25
- ### Using permissions on one model through another model
23
+ Once this config file is created, you can launch the following command.
24
+
25
+ rails generate dynamican_migration
26
+
27
+ This command will generate a migration file in your project. Inside this migration, the `permission_connectors` table will have a reference column for the models you configured in the config file. If you want to add the feature to a new model after your migrations are already run (and cannot be rollbacked) you need to create a new migration to add the corresponding columns in the `permission_connectors` table.
28
+
29
+ ### Using a model permissions on another model
26
30
 
27
- I wanted to have the possibility to assign permissions both directly to my User model and my Role model, so that if the User had one permission and one of its Role had another, the User could benefit from both. So i assigned the feature (as explained above) to both models and then decorated my User model like this
31
+ I wanted to have the possibility to assign permissions both directly to my User model and my Role model, so that if the User had one permission and one of its Role had another, the User could benefit from both. So i assigned the feature (as explained above) to both models and then decorated my User model like following.
28
32
 
29
33
  module Decorators
30
34
  module Models
@@ -52,7 +56,9 @@ I wanted to have the possibility to assign permissions both directly to my User
52
56
  end
53
57
  end
54
58
 
55
- I personally have put this in `app/decorators/models/user/dynamican_overrides.rb` (you need to load the folder if you don't already have it) but you can make it work as you please. I recommend to keep it separate from the original User model though.
59
+ I personally have put this in `app/decorators/models/user/dynamican_overrides.rb` (you need to make rails load the folder if); you can make it work as you please but i recommend to keep it separate from the original User model.
60
+
61
+ WARNING: if you have done this override, User `permissions` and `permission_connectors` methods are not relations anymore, so methods like `<<` and `create` won't work on them.
56
62
 
57
63
  ## Usage
58
64
 
@@ -65,25 +71,27 @@ Create one `Dynamican::Permission` for each pair of action-object you need. For
65
71
  p3 = Dynamican::Permission.create(action: 'update', object_name: 'order')
66
72
  p4 = Dynamican::Permission.create(action: 'delete', object_name: 'order')
67
73
 
68
- To assign one of these permissions to your Role or User, you need to create a `Dynamican::PermissionConnector` like this
74
+ To assign one of these permissions to your Role or User, you need to create a `Dynamican::PermissionConnector` like follows.
69
75
 
70
- user.permission_connectors.create(permission: p1)
76
+ role.permission_connectors.create(permission: p1)
71
77
 
72
78
  Or simply
73
79
 
74
- user.permissions << p1
80
+ role.permissions << p1
81
+
82
+ Now your Role is considered able to create orders and you can evaluate permissions with `can?` method.
75
83
 
76
- Now your user is considered able to create orders and you can check the permissions:
84
+ role.can? :create, :order
77
85
 
78
- user.can? :create, :order
79
86
  # Returns true
80
87
 
81
- user.can? :read, :order
88
+ role.can? :read, :order
89
+
82
90
  # Returns false
83
91
 
84
92
  You can pass as second argument (the object) a symbol, a string, the class itself and also the instance (instances are used for condition evaluations).
85
- You can also pass an array of these elements and permissions for all elements will be evaluated. The `can?` method will return true only if all permissions are evaluated positively.
86
- You can also create custom permissions which don't need an object, simply leaving the `object_name` empty. Let's say you want to give permission to a certain user to dance
93
+ If you pass an array of these elements, permissions for all single element will be evaluated. The `can?` method will return true only if permissions to all objects are evaluated positively.
94
+ You can also create custom permissions which don't need an object, simply leaving the `object_name` empty. Let's say you want to give permission to a certain user to dance.
87
95
 
88
96
  p5 = Dynamican::Permission.create(action: 'dance')
89
97
 
@@ -96,23 +104,23 @@ Call the `can?` method without any second argument
96
104
  # Returns true
97
105
 
98
106
 
99
- ## Conditions
107
+ ### Conditions
100
108
 
101
- You can link a `Dynamican::PermissionConnector` to as many conditions as you want.
109
+ You can link a `Dynamican::PermissionConnector` to as many conditions as you want. In order to evaluate its conditions, the `conditional` property of the permission_connector needs to be set as `true` (default to `false`)
102
110
 
103
- Conditions are created like this
111
+ Conditions are created like this.
104
112
 
105
113
  permission_connector.conditions.create(statement: '@user.orders.count < 5')
106
114
  permission_connector.conditions.create(statement: '@object.field.present?')
107
115
 
108
- You can store in conditions statements whatever conditions you like in plain ruby and the string will be evaulated. Inside the statements, object have to be called as instance variables. These instance variables need to be present and can be declared as follows:
116
+ You can store in conditions statements whatever conditions you like in plain ruby and the string will be evaulated. Inside the statements, object have to be called as instance variables. These instance variables indeed need to be present and can be declared in a few ways.
109
117
 
110
- 1. The model name of the instance you called `can?` from, like the user, will be defined automatically based on model name so if you call `user.can?` you will have `@user` variable defined.
118
+ 1. The model name of the instance you called `can?` from, like the user, will be defined automatically based on model name, so if you call `user.can?` you will have `@user` variable defined.
111
119
  2. The object you pass as second argument (which should match the `object_name` of your permission) will be defined as `@object`, so if you call `user.can? :read, @order` you will have `@object` variable defined containing your `@order`.
112
120
  3. You can pass as third argument an hash of objects like this `user.can? :read, @order, time: Time.zone.now, whatever: @you_want` and you will have `@time` and `@whatever` variables defined.
113
121
 
114
- WARNING: since the condition statement gets evaluated, i recommend not to allow anyone except project developers to create conditions to prevent malicious code from being executed.
122
+ WARNING: since the condition statement gets evaluated, i recommend not to allow anyone except project developers to create conditions, in order to prevent malicious code from being executed.
115
123
 
116
- If one `Dynamican::PermissionConnector` is linked to many conditions, the model will be allowed to make that action only if all conditions are true. If you want to set alternative conditions, you should store the or conditions inside the same statement, like this:
124
+ If one `Dynamican::PermissionConnector` is linked to many conditions, the model will be allowed to make that action only if all conditions are true. If you want to set alternative conditions, you should store the `or` conditions inside the same condition statement, like this:
117
125
 
118
126
  condition.statement = '@user.nice? || @user.polite?'
data/dynamican.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'dynamican'
3
- s.version = '0.1.7'
4
- s.date = '2020-04-12'
3
+ s.version = '0.1.9'
4
+ s.date = '2020-04-18'
5
5
  s.summary = "Dynamic permissions"
6
6
  s.description = "Dynamic and flexible database configurable permissions for your application"
7
7
  s.authors = ["Valerio Bellaveglia"]
data/lib/dynamican.rb CHANGED
@@ -4,3 +4,4 @@ require 'dynamican/model'
4
4
  require 'models/dynamican/condition'
5
5
  require 'models/dynamican/permission_connector'
6
6
  require 'models/dynamican/permission'
7
+ require 'generators/create_dynamican_migration'
@@ -0,0 +1,59 @@
1
+ require 'rails/generators'
2
+
3
+ class DynamicanMigrationGenerator < Rails::Generators::Base
4
+
5
+ def create_migration_file
6
+ create_file "db/migrate/#{Time.zone.now.strftime("%Y%m%d%H%M%S")}_dynamican_migration.rb", migration_data
7
+ end
8
+
9
+ private
10
+
11
+ def migration_data
12
+ <<MIGRATION
13
+ class DynamicanMigration < ActiveRecord::Migration[5.2]
14
+ # 0.1.2 Release
15
+ def change
16
+ unless table_exists? :permissions
17
+ create_table :conditions do |t|
18
+ t.string :description
19
+ t.string :statement
20
+
21
+ t.timestamps
22
+ end
23
+
24
+ create_table :permissions do |t|
25
+ t.string :action
26
+ t.string :object_name
27
+
28
+ t.timestamps
29
+ end
30
+
31
+ create_table :permission_connectors do |t|
32
+ #{create_migration_associations_data}
33
+ t.references :permission
34
+ t.boolean :conditional, default: false
35
+
36
+ t.timestamps
37
+ end
38
+
39
+ create_table :conditions_permission_connectors do |t|
40
+ t.bigint :condition_id
41
+ t.bigint :permission_connector_id
42
+ end
43
+ end
44
+ end
45
+ end
46
+ MIGRATION
47
+ end
48
+
49
+ def create_migration_associations_data
50
+ migration_associations_data = ""
51
+ associations = Dynamican.configuration.associations.keys
52
+
53
+ associations.each do |association|
54
+ migration_associations_data += "t.references :#{association}#{"\n " unless association == associations.last}"
55
+ end
56
+
57
+ migration_associations_data
58
+ end
59
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamican
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.1.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Valerio Bellaveglia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-12 00:00:00.000000000 Z
11
+ date: 2020-04-18 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Dynamic and flexible database configurable permissions for your application
14
14
  email:
@@ -23,10 +23,10 @@ files:
23
23
  - lib/dynamican/configuration.rb
24
24
  - lib/dynamican/evaluator.rb
25
25
  - lib/dynamican/model.rb
26
+ - lib/generators/dynamican_migration_generator.rb
26
27
  - lib/models/dynamican/condition.rb
27
28
  - lib/models/dynamican/permission.rb
28
29
  - lib/models/dynamican/permission_connector.rb
29
- - migrations/0.1.2/dynamican_create_database_structure.rb
30
30
  homepage: https://github.com/ValerioBellaveglia/Dynamican
31
31
  licenses:
32
32
  - MIT
@@ -1,31 +0,0 @@
1
- class DynamicanCreateDatabaseStructure < ActiveRecord::Migration[5.2]
2
- def change
3
- create_table :conditions do |t|
4
- t.string :description
5
- t.string :statement
6
-
7
- t.timestamps
8
- end
9
-
10
- create_table :permissions do |t|
11
- t.string :action
12
- t.string :object_name
13
-
14
- t.timestamps
15
- end
16
-
17
- create_table :permission_connectors do |t|
18
- t.references :user
19
- t.references :role
20
- t.references :permission
21
- t.boolean :conditional, default: false
22
-
23
- t.timestamps
24
- end
25
-
26
- create_table :conditions_permission_connectors do |t|
27
- t.bigint :condition_id
28
- t.bigint :permission_connector_id
29
- end
30
- end
31
- end