glib-web 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '00370028bd3cdc3097c1b40e128c34ec08271d2858b5a83d2c54ebceb5f18c6e'
4
- data.tar.gz: 5021c723ca5ef541455c0497fc0a25f86945b7d99383698fb76d587d034f2f9b
3
+ metadata.gz: 38b5751f1b2684f0d68bacb791098fc4aab5ab6b42cb25f1891a1f27bbdbbc8f
4
+ data.tar.gz: eed1f00a5ccd846f36d7291620f45f8702a63f80ffe8b94364243a5f1ce3cb55
5
5
  SHA512:
6
- metadata.gz: f7cc0a4fa5a08a8673e3306dfb91ca07e341c395b4a3f1e4cce985b7da72e394844ff5596087e657b15a1c610366aa34f5958446b40ba27c7a3ce3fc9afbd253
7
- data.tar.gz: 9c4b027e7025dcb06a7734839fde49dc8138ae5865e442faebe0f0e715dc9d3077747f1e52b6f5198337d36635de9af89f52970abcf82a24929dc23ee5877948
6
+ metadata.gz: a464dbf43a08c5f9b131c5e18b48bda98d40ef29e0298827b78e901f667df0901f227be11809feb39be6d55aa1b9b09133cfa119d06829f5dd663a569ef2e6eb
7
+ data.tar.gz: ca3b4567e5344a9d057c66d772aded64ba86b810d650837b1581eb40a3a981eed7e646c58e5915964f3a612088b0451a8cd490542e51d288bd5e4f30ba5d28a3
@@ -0,0 +1,98 @@
1
+ module Glib::Auth
2
+ module Policy
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ include Pundit
7
+ include Overrides
8
+ extend ClassMethods
9
+
10
+ # TODO: Ultimately we want to uncomment this line, but:
11
+ # - Need to be able to set aside some time to run rspec tests to ensure nothing gets broken
12
+ # - Need to find a solution where we can reuse a single public policy
13
+ # after_action :verify_authorized
14
+
15
+ helper_method :policy, :can?, :cannot?
16
+
17
+ end
18
+
19
+ module Overrides
20
+ public # Override
21
+ def policy(record)
22
+ return @__pundit_policy if defined? @__pundit_policy
23
+
24
+ if record.is_a?(Symbol) && record.to_s.ends_with?('_admin')
25
+ policy_class = CommonAdminPolicy
26
+ else
27
+ policy_class = Pundit::PolicyFinder.new(record).policy
28
+ end
29
+ raise "Policy not found for #{record.class}" unless policy_class
30
+ @__pundit_policy = policy_class.new(current_user, record, self, request, params, *policy_class.args_builder.call(self))
31
+ end
32
+ end
33
+
34
+ public
35
+ def raise_access_denied(record)
36
+ # raise Pundit::NotAuthorizedError.new(record: record, policy: policy(record), query: "#{action_name}?")
37
+ raise UnauthorizedError.new(record: record, policy: policy(record), query: "#{action_name}?")
38
+ end
39
+
40
+ public
41
+ def can?(action, record)
42
+ policy(record).send("#{action}?")
43
+ end
44
+
45
+ public
46
+ def cannot?(action, record)
47
+ !policy(record).send("#{action}?")
48
+ end
49
+
50
+
51
+
52
+ class UnauthorizedError < Pundit::NotAuthorizedError
53
+ end
54
+
55
+
56
+
57
+ module ClassMethods
58
+ # Inspired from https://github.com/ryanb/cancan/wiki/Non-RESTful-Controllers
59
+ public
60
+ def authorize_resource(*args)
61
+ options = args.extract_options!
62
+ resource_name = args.first
63
+
64
+ self.before_action(options.slice(:only, :except, :if, :unless)) do |controller|
65
+ resource_name ||= resource_name_from_controller
66
+
67
+ if !(resource_key = options[:class]).nil?
68
+ resource = case resource_key
69
+ when false
70
+ resource_name.to_sym
71
+ when Symbol, Class
72
+ resource_key
73
+ else
74
+ raise "Invalid resource class: #{resource_key}"
75
+ end
76
+
77
+ authorize resource
78
+ # if (policy = policy(resource)) && policy.class.instance_variable_defined?(:@manage_permission)
79
+ # skip_authorization if policy.manage?
80
+ # else
81
+ # authorize resource
82
+ # end
83
+ elsif (resource_instance = controller.instance_variable_get("@#{resource_name}"))
84
+ authorize resource_instance
85
+ else
86
+ authorize resource_name.camelize.constantize
87
+ end
88
+
89
+ verify_authorized
90
+ end
91
+ end
92
+ end
93
+
94
+ def resource_name_from_controller
95
+ params[:controller].split('/').last.singularize
96
+ end
97
+ end
98
+ end
@@ -2,15 +2,14 @@ module Glib::Json::DynamicText
2
2
  def __json_dynamic_text_perform
3
3
  if (hash = json_transformation_start).is_a?(Hash)
4
4
  @__specs = {}
5
-
5
+
6
6
  crawl hash['header']&.[]('childViews')
7
7
  crawl hash['body']&.[]('childViews')
8
8
  crawl hash['footer']&.[]('childViews')
9
9
 
10
- # TODO: retrieve texts from dynamictextreader
11
- # translated_texts = retrieve_remote_texts(@__specs.keys)
10
+ translated_texts = retrieve_remote_texts(@__specs.keys)
12
11
 
13
- translated_texts = retrieve_example_texts(@__specs.keys)
12
+ # translated_texts = retrieve_example_texts(@__specs.keys)
14
13
  translated_texts.each do |key, value|
15
14
  @__specs[key].each do |spec|
16
15
  spec.substitute_with(value)
@@ -32,6 +31,11 @@ module Glib::Json::DynamicText
32
31
  translated_texts
33
32
  end
34
33
 
34
+ def retrieve_remote_texts(keys)
35
+ response = RestClient.get(ENV['DTR_URL'], { params: { keys: keys } })
36
+ JSON.parse(response)
37
+ end
38
+
35
39
  def crawl views
36
40
  Glib::Json::DynamicText::crawl_multiple views, ->(view) do
37
41
  extract_spec(view, 'text')
@@ -52,7 +56,7 @@ module Glib::Json::DynamicText
52
56
  view[prop] = text.gsub(/\{\{(\w+)\}\}/) { args.fetch($1, "{{#{$1}}}") }
53
57
  end
54
58
  end
55
-
59
+
56
60
  def self.crawl_multiple views, block
57
61
  if views.is_a? Array
58
62
  views.each do |view|
@@ -85,7 +89,7 @@ module Glib::Json::DynamicText
85
89
  # panels/split
86
90
  # crawl_multiple view['leftViews'], block
87
91
  # crawl_multiple view['rightViews'], block
88
-
92
+
89
93
  # Split panel
90
94
  crawl_vertical_content view['left'], block
91
95
  crawl_vertical_content view['center'], block
@@ -82,6 +82,7 @@ module Glib
82
82
  string :body
83
83
  string :tag
84
84
  int :timeout
85
+ action :onClick
85
86
  end
86
87
 
87
88
  end
@@ -0,0 +1,148 @@
1
+ # The main purpose of this is for security. If it is important to display useful error message or to provide a "banana", then
2
+ # it's better to perform an explicit check (e.g. as a validation in the model or using a before_action).
3
+ module Glib
4
+ class ApplicationPolicy
5
+ attr_reader :user, :record, :controller, :request, :params
6
+
7
+ private
8
+ def initialize(user, record, controller, request, params)
9
+ @user = user
10
+ @record = record
11
+ @controller = controller
12
+ @request = request
13
+ # Don't get params from request because we might not have a proper request object. This might execute in Sidekiq.
14
+ # See Presenter::Model::inside_mock_controller()
15
+ @params = params
16
+ end
17
+
18
+ class << self
19
+ attr_reader :catch_all
20
+
21
+ # This is to define the authorization logic for an action (or a group of actions). It's different from controller's
22
+ # authorize().
23
+ private # Used by child
24
+ def authorize(*actions, &block)
25
+ actions.each do |action|
26
+ if action == :manage
27
+ # Serve as a catch-all to all actions that have not been specified in the policy.
28
+ @catch_all = block
29
+ else
30
+ method_name = "#{action}?"
31
+ # Avoid accidentally redefining multiple times from child policies. But it's okay if the child policy
32
+ # wants to override the parent's authorization method.
33
+ raise "Action authorization has been declared: #{action}" if instance_methods(false).include?(method_name.to_sym)
34
+ define_method method_name, &block
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ private
41
+ def catch_all
42
+ self.class.catch_all
43
+ end
44
+
45
+ private
46
+ # To ensure the block is called on the policy's instance instead class.
47
+ def call_catch_all
48
+ instance_eval(&catch_all)
49
+ end
50
+
51
+ authorize :index do
52
+ # We need this line because in `index` action, this method will be called instead of method_missing().
53
+ # Having this line ensures that the catch_all behaviour works according to the priority below:
54
+ # - child_policy#index?
55
+ # - child_policy#manage? -- catch_all
56
+ # - application_policy@index?
57
+ return call_catch_all if catch_all
58
+
59
+ false
60
+ end
61
+
62
+ authorize :show do
63
+ return call_catch_all if catch_all
64
+
65
+ scope.where(id: record.id).exists?
66
+ end
67
+
68
+ authorize :create do
69
+ return call_catch_all if catch_all
70
+
71
+ false
72
+ end
73
+
74
+ authorize :new do
75
+ return call_catch_all if catch_all
76
+
77
+ create?
78
+ end
79
+
80
+ authorize :update do
81
+ return call_catch_all if catch_all
82
+
83
+ false
84
+ end
85
+
86
+ authorize :edit do
87
+ return call_catch_all if catch_all
88
+
89
+ update?
90
+ end
91
+
92
+ authorize :destroy do
93
+ return call_catch_all if catch_all
94
+
95
+ false
96
+ end
97
+
98
+ public
99
+ def method_missing(name, *args, &block)
100
+ if name.to_s.end_with?('?') && catch_all
101
+ call_catch_all
102
+ else
103
+ super
104
+ end
105
+ end
106
+
107
+ public
108
+ def scope
109
+ Pundit.policy_scope!(user, record.class)
110
+ end
111
+
112
+ private # Used by child
113
+ def public?
114
+ true
115
+ end
116
+
117
+ # # TODO: Revise because it seems there is no justification for allowing owner to see any of the deleted entities, which include User, Guild, and Post
118
+ # private # Used by child
119
+ # def not_deleted_unless_owner_or_moderator?(&block)
120
+ # block ||= lambda { |unused_arg| @user.moderator? }
121
+ # !@record.deleted? || (@user && (@user.id == @record.user_owner_id || block.call(@record)))
122
+ # end
123
+
124
+ # private # Used by child
125
+ # def not_deleted_unless_moderator?(&block)
126
+ # block ||= lambda { |unused_arg| @user.moderator? }
127
+ # !@record.deleted? || (@user && block.call(@record))
128
+ # end
129
+
130
+ public
131
+ def self.args_builder
132
+ Proc.new { |controller| [] }
133
+ end
134
+
135
+ class Scope
136
+ attr_reader :user, :scope
137
+
138
+ def initialize(user, scope)
139
+ @user = user
140
+ @scope = scope
141
+ end
142
+
143
+ def resolve
144
+ scope
145
+ end
146
+ end
147
+ end
148
+ end
@@ -6,7 +6,9 @@ json_ui_page json do |page|
6
6
  page.list firstSection: ->(section) do
7
7
  section.rows builder: ->(template) do
8
8
  template.thumbnail title: 'Send Desktop Notification', onClick: ->(action) do
9
- action.dialogs_notification title: 'Hello World', body: 'Body Message'
9
+ action.dialogs_notification title: 'Hello World', body: 'Body Message', onClick: ->(action) do
10
+ action.dialogs_alert message: 'TODO'
11
+ end
10
12
  end
11
13
  end
12
14
  end
@@ -1,4 +1,4 @@
1
- json.title 'Panels'
1
+ json.title 'Responsive Panels'
2
2
 
3
3
  json_ui_page json do |page|
4
4
  render "#{@path_prefix}/nav_menu", json: json, page: page
@@ -7,37 +7,49 @@ json_ui_page json do |page|
7
7
  scroll.label text: 'Shrink the browser\'s width to see how the column panels are rearranged. On mobile screens, they are always arranged vertically'
8
8
 
9
9
  scroll.spacer height: 20
10
- scroll.h2 text: 'Responsive panel with 12 columns'
10
+ scroll.h2 text: 'With 12 columns'
11
11
  scroll.spacer height: 6
12
12
  scroll.panels_responsive width: 'matchParent', childViews: ->(horizontal) do
13
- horizontal.panels_column lg: 8, backgroundColor: '#c3cad2', childViews: ->(column) do
13
+ horizontal.panels_column lg: { cols: 8 }, backgroundColor: '#c3cad2', childViews: ->(column) do
14
14
  column.button text: '1'
15
15
  end
16
- horizontal.panels_column lg: 4, backgroundColor: '#b3bac2', childViews: ->(column) do
16
+ horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#b3bac2', childViews: ->(column) do
17
17
  column.button text: '2'
18
18
  end
19
19
  end
20
20
 
21
21
  scroll.spacer height: 20
22
- scroll.h2 text: 'Responsive panel with more than 12 columns'
22
+ scroll.h2 text: 'With more than 12 columns'
23
23
  scroll.spacer height: 6
24
24
  scroll.panels_responsive width: 'matchParent', childViews: ->(horizontal) do
25
- horizontal.panels_column lg: 4, backgroundColor: '#c3cad2', childViews: ->(column) do
25
+ horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#c3cad2', childViews: ->(column) do
26
26
  column.button text: '1'
27
27
  end
28
- horizontal.panels_column lg: 4, backgroundColor: '#b3bac2', childViews: ->(column) do
28
+ horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#b3bac2', childViews: ->(column) do
29
29
  column.button text: '2'
30
30
  end
31
- horizontal.panels_column lg: 4, backgroundColor: '#c3cad2', childViews: ->(column) do
31
+ horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#c3cad2', childViews: ->(column) do
32
32
  column.button text: '3'
33
33
  end
34
- horizontal.panels_column lg: 4, backgroundColor: '#b3bac2', childViews: ->(column) do
34
+ horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#b3bac2', childViews: ->(column) do
35
35
  column.button text: '4'
36
36
  end
37
- horizontal.panels_column lg: 4, backgroundColor: '#c3cad2', childViews: ->(column) do
37
+ horizontal.panels_column lg: { cols: 4 }, backgroundColor: '#c3cad2', childViews: ->(column) do
38
38
  column.button text: '5'
39
39
  end
40
40
  end
41
41
 
42
+ scroll.spacer height: 20
43
+ scroll.h2 text: 'With responsive paddings'
44
+ scroll.spacer height: 6
45
+ scroll.panels_responsive width: 'matchParent', childViews: ->(horizontal) do
46
+ horizontal.panels_column lg: { cols: 8, padding: { right: 20 } }, childViews: ->(column) do
47
+ column.button width: 'matchParent', text: '1'
48
+ end
49
+ horizontal.panels_column lg: { cols: 4 }, childViews: ->(column) do
50
+ column.button width: 'matchParent', text: '2'
51
+ end
52
+ end
53
+
42
54
  end
43
55
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glib-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
@@ -30,6 +30,34 @@ dependencies:
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: 6.1.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: pundit
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 2.1.0
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 2.1.0
47
+ - !ruby/object:Gem::Dependency
48
+ name: rest-client
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '2.1'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '2.1'
33
61
  description:
34
62
  email: ''
35
63
  executables: []
@@ -40,6 +68,7 @@ files:
40
68
  - app/controllers/concerns/application/json/transformation.rb
41
69
  - app/controllers/concerns/application/json/ui.rb
42
70
  - app/controllers/concerns/application/json/validation.rb
71
+ - app/controllers/concerns/glib/auth/policy.rb
43
72
  - app/controllers/concerns/glib/json/dynamic_text.rb
44
73
  - app/controllers/concerns/glib/json/libs.rb
45
74
  - app/controllers/concerns/glib/json/transformation.rb
@@ -63,6 +92,7 @@ files:
63
92
  - app/helpers/glib/json_ui/view_builder/panels.rb
64
93
  - app/models/glib/dynamic_text_record.rb
65
94
  - app/models/glib/text.rb
95
+ - app/policies/glib/application_policy.rb
66
96
  - app/views/app/views/json_ui/vue/renderer.html.erb
67
97
  - app/views/json_ui/garage/_nav_menu.json.jbuilder
68
98
  - app/views/json_ui/garage/actions/index.json.jbuilder