wire-framework 0.1.4.26 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/lib/closet/auth.rb CHANGED
@@ -1,57 +1,41 @@
1
+ ##
2
+ # Copyright 2017 Bryan T. Meyers
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ ##
1
16
 
2
17
  module Wire
3
- # Auth is a module for handling authorization
4
- # @author Bryan T. Meyers
5
- module Auth
18
+ # Auth is a module for handling authorization
19
+ # @author Bryan T. Meyers
20
+ module Auth
6
21
 
7
- # Get the allowed actions for the current URI
8
- # @param [Hash] context the context for this request
9
- # @return [Array] the allowed actions for this URI
10
- def actions_allowed(context)
11
- actions = []
12
- app = context.app
13
- user = context.user
14
- if app
15
- auth = app[:auth]
16
- level = auth[:level]
17
- case level
18
- when :any
19
- actions = [:create, :read, :readAll, :update, :delete]
20
- when :app
21
- actions = auth[:handler].actions_allowed(context)
22
- when :read_only
23
- actions = [:read,:readAll]
24
- when :user
25
- if user == auth[:user]
26
- actions = [:create, :read, :readAll, :update, :delete]
27
- end
28
- end
29
- end
30
- actions
31
- end
32
-
33
- # Setup auth for an App
34
- # @param [Symbol] level the type of authz to perform
35
- # @param [Proc] block setup for the authz
36
- # @return [void]
37
- def auth(level, &block)
38
- $current_app[:auth] = { level: level }
39
- unless (level == :any) || (block.nil?)
40
- Docile.dsl_eval(self, &block)
41
- end
42
- end
43
-
44
- # Select handler for :app level of auth
45
- # @param [Module] handler the type of authz to perform
46
- # @return [void]
47
- def handler(handler)
48
- $current_app[:auth][:handler] = handler
49
- end
50
-
51
- # Select user for :user level of auth
52
- # @return [void]
53
- def user(user)
54
- $current_app[:auth][:user] = user
55
- end
56
- end
22
+ # Get the allowed actions for the current URI
23
+ # @param [Hash] context the context for this request
24
+ # @return [Array] the allowed actions for this URI
25
+ def actions_allowed(context)
26
+ if context.config['auth_read_only']
27
+ [:read, :readAll]
28
+ elsif context.config['auth_user']
29
+ if context.user == context.config['auth_user']
30
+ [:create, :read, :readAll, :update, :delete]
31
+ else
32
+ []
33
+ end
34
+ elsif context.config['auth_handler']
35
+ context.config['auth_handler'].actions_allowed(context)
36
+ else
37
+ [:create, :read, :readAll, :update, :delete]
38
+ end
39
+ end
40
+ end
57
41
  end
@@ -0,0 +1,34 @@
1
+ ##
2
+ # Copyright 2017 Bryan T. Meyers
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ ##
16
+
17
+ require 'yaml'
18
+
19
+ module Wire
20
+ module Config
21
+ def self.read_config_dir(dir, callback)
22
+ configs = {}
23
+ Dir[File.join(dir, '*.yaml')].each do |entry|
24
+ name = File.basename(entry, '.yaml')
25
+ config = YAML.load_file(File.join(dir, entry))
26
+ if callback
27
+ config = callback.call(config)
28
+ end
29
+ configs[name] = config
30
+ end
31
+ configs
32
+ end
33
+ end
34
+ end
@@ -1,106 +1,150 @@
1
+ ##
2
+ # Copyright 2017 Bryan T. Meyers
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ ##
16
+
17
+ require 'json'
18
+ require 'rest-less'
19
+
1
20
  module Wire
2
- # Context is a class containing request information
3
- # @author Bryan T. Meyers
21
+ # Context is a class containing information related to the current request
22
+ # @author Bryan T. Meyers
23
+
24
+ class Context
25
+ #@!attribute [r] action
26
+ # @return [Symbol] the action
27
+ #@!attribute [r] app
28
+ # @return [Hash] the name of the Wire::App
29
+ #@!attribute [r] body
30
+ # @return [String] the unparsed body
31
+ #@!attribute [r] config
32
+ # @return [Hash] the Wire::App configuration
33
+ #@!attribute [r] json
34
+ # @return [Hash] the JSON parsed body
35
+ #@!attribute [r] query
36
+ # @return [Hash] the parsed query string
37
+ #@!attribute [r] query_string
38
+ # @return [String] the raw query string
39
+ #@!attribute [r] rack_env
40
+ # @return [Hash] the raw Rack environment
41
+ #@!attribute [r] referer
42
+ # @return [Array] the referer URI
43
+ #@!attribute [r] resource
44
+ # @return [Symbol] the name of the resource
45
+ #@!attribute [r] uri
46
+ # @return [Array] the complete URI
47
+ #@!attribute [r] user
48
+ # @return [String] the REMOTE_USER
49
+ #@!attribute [r] verb
50
+ # @return [Symbol] the HTTP verb
51
+
52
+ attr_reader :action, :app, :body, :rack_env, :json, :query,
53
+ :query_string, :referer, :resource, :type,
54
+ :uri, :user, :verb
55
+ attr_writer :referer
4
56
 
5
- class Context
6
- #@!attribute [r] action
7
- # @return [Symbol] the action for the current request
8
- #@!attribute [r] app
9
- # @return [Hash] the Wire::App configuration for the current request
10
- #@!attribute [r] body
11
- # @return [String] the unparsed body of the current request
12
- #@!attribute [r] env
13
- # @return [Hash] the raw Rack environment of the current request
14
- #@!attribute [r] json
15
- # @return [Hash] the JSON parsed body of the current request
16
- #@!attribute [r] query
17
- # @return [Hash] the parsed query string of the current request
18
- #@!attribute [r] query_string
19
- # @return [String] the raw query string of the current request
20
- #@!attribute [r] referer
21
- # @return [Array] the referer URI of the current request
22
- #@!attribute [r] resource
23
- # @return [Symbol] the Wire::Resource configuration of the current request
24
- #@!attribute [r] type
25
- # @return [Module] the Wire::App of the current request
26
- #@!attribute [r] uri
27
- # @return [Array] the URI of the current request
28
- #@!attribute [r] user
29
- # @return [String] the REMOTE_USER of the current request
30
- #@!attribute [r] verb
31
- # @return [Symbol] the HTTP verb of the current request
57
+ # Maps HTTP verbs to actions
58
+ HTTP_ACTIONS = {
59
+ 'GET': :read,
60
+ 'HEAD': :read,
61
+ 'POST': :create,
62
+ 'PUT': :update,
63
+ 'DELETE': :delete
64
+ }
32
65
 
33
- attr_reader :action, :app, :body, :env, :json, :query,
34
- :query_string, :referer, :resource, :type,
35
- :uri, :user, :verb
36
- attr_writer :referer
66
+ # Maps HTTP verbs to Symbols
67
+ HTTP_VERBS = {
68
+ 'GET': :get,
69
+ 'HEAD': :head,
70
+ 'POST': :post,
71
+ 'PUT': :put,
72
+ 'DELETE': :delete
73
+ }
37
74
 
38
- # Maps HTTP verbs to actions
39
- HTTP_ACTIONS = {
40
- 'GET' => :read,
41
- 'HEAD' => :read,
42
- 'POST' => :create,
43
- 'PUT' => :update,
44
- 'DELETE' => :delete
45
- }
75
+ # Add user info to session
76
+ # @param [Hash] env the Rack environment
77
+ # @return [Hash] the updated environment
78
+ def update_session(env)
79
+ user = env['HTTP_REMOTE_USER']
80
+ unless user.nil? or user.empty? or user.eql? 'nobody' or user.eql? '(null)'
81
+ env['rack.session']['user'] = user
82
+ end
83
+ env['REMOTE_USER'] = env['rack.session']['user'] ? env['rack.session']['user'] : nil
84
+ env
85
+ end
46
86
 
47
- # Maps HTTP verbs to Symbols
48
- HTTP_VERBS = {
49
- 'GET' => :get,
50
- 'HEAD' => :head,
51
- 'POST' => :post,
52
- 'PUT' => :put,
53
- 'DELETE' => :delete
54
- }
87
+ # Builds a new Context
88
+ # @param [Hash] env the Rack environment
89
+ # @return [Context] a new Context
90
+ def initialize(env)
91
+ @rack_env = update_session(env)
92
+ @user = env['rack.session']['user']
93
+ @verb = HTTP_VERBS[env['REQUEST_METHOD']]
94
+ @action = HTTP_ACTIONS[env['REQUEST_METHOD']]
95
+ @uri = env['REQUEST_URI'].split('?')[0].split('/')
96
+ if env['HTTP_REFERER']
97
+ @referer = env['HTTP_REFERER'].split('/')
98
+ else
99
+ @referer = ['http:', '', env['HTTP_HOST']].concat(@uri[1...@uri.length])
100
+ end
101
+ @config = $wire_apps[@uri[1]]
102
+ if @config
103
+ @app = @uri[1]
104
+ @resource = @uri[2]
105
+ @id = context.uri[3...context.uri.length].join('/')
106
+ else
107
+ throw Exception.new("App: #{@uri[1]} is Undefined")
108
+ end
109
+ @query = {}
110
+ env['QUERY_STRING'].split('&').each do |q|
111
+ param = q.split('=')
112
+ @query[param[0].to_sym] = param[1]
113
+ end
114
+ @query_string = env['QUERY_STRING']
115
+ if env['rack.input']
116
+ @body = env['rack.input'].read
117
+ begin
118
+ @json = JSON.parse_clean(@body)
119
+ rescue JSON::ParserError
120
+ $stderr.puts 'Warning: Failed to parse body as JSON'
121
+ end
122
+ end
123
+ end
55
124
 
56
- # Add user info to session
57
- # @param [Hash] env the Rack environment
58
- # @return [Hash] the updated environment
59
- def update_session(env)
60
- user = env['HTTP_REMOTE_USER']
61
- unless user.nil? or user.empty? or user.eql? 'nobody' or user.eql? '(null)'
62
- env['rack.session']['user'] = user
63
- end
64
- env['REMOTE_USER'] = env['rack.session']['user'] ? env['rack.session']['user'] : nil
65
- env
66
- end
125
+ CONVERT = {
126
+ create: :post,
127
+ read: :get,
128
+ readAll: :get,
129
+ update: :put,
130
+ delete: :delete
131
+ }
67
132
 
68
- # Builds a new Context
69
- # @param [Hash] env the Rack environment
70
- # @return [Context] a new Context
71
- def initialize(env)
72
- @env = update_session(env)
73
- @user = env['rack.session']['user']
74
- @verb = HTTP_VERBS[env['REQUEST_METHOD']]
75
- @action = HTTP_ACTIONS[env['REQUEST_METHOD']]
76
- @uri = env['REQUEST_URI'].split('?')[0].split('/')
77
- if env['HTTP_REFERER']
78
- @referer = env['HTTP_REFERER'].split('/')
79
- else
80
- @referer = [ 'http:' , '' , env['HTTP_HOST']].concat(@uri[1...@uri.length])
81
- end
82
- app = $apps[@uri[1]]
83
- if app
84
- @app = app
85
- @resource = app[:resources][@uri[2]]
86
- @type = app[:type]
87
- else
88
- throw Exception.new("App: #{@uri[1]} is Undefined")
89
- end
90
- @query = {}
91
- env['QUERY_STRING'].split('&').each do |q|
92
- param = q.split('=')
93
- @query[param[0].to_sym] = param[1]
94
- end
95
- @query_string = env['QUERY_STRING']
96
- if env['rack.input']
97
- @body = env['rack.input'].read
98
- begin
99
- @json = JSON.parse_clean(@body)
100
- rescue JSON::ParserError
101
- $stderr.puts 'Warning: Failed to parse body as JSON'
102
- end
103
- end
104
- end
105
- end
133
+ # Proxy method used when forwarding requests
134
+ # @param [Symbol] method the action to use when forwarding
135
+ # @return [Response] a Rack Response triplet, or status code
136
+ def forward(method)
137
+ headers = { referer: @referer.join('/'),
138
+ remote_user: @user }
139
+ verb = CONVERT[method]
140
+ uri = "http://#{@app['remote']}/#{@uri[2]}"
141
+ if [:update, :read, :delete].include?(method)
142
+ uri += "/#{@uri[3...@uri.length].join('/')}"
143
+ end
144
+ uri += '?' + @query_string
145
+ body = [:create, :update].include?(method) ? @body : nil
146
+ $stderr.puts "#{verb.upcase}: Forward Request to #{uri}"
147
+ RL.request verb, uri, headers, body
148
+ end
149
+ end
106
150
  end
@@ -1,46 +1,49 @@
1
- module Wire
2
- # Renderer is a module for mapping mime to rendering templates
3
- # @author Bryan T. Meyers
4
- module Renderer
1
+ ##
2
+ # Copyright 2017 Bryan T. Meyers
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ ##
16
+
17
+ require 'tilt'
18
+ require_relative 'config'
5
19
 
6
- # Setup a Renderer
7
- # @param [Class] klass the type of renderer to use
8
- # @param [Proc] block for configuring this renderer
9
- # @return [void]
10
- def renderer(klass, &block)
11
- $current_renderer = klass
12
- $current_editor = nil
13
- Docile.dsl_eval(self, &block)
14
- end
20
+ module Wire
21
+ # Renderer is a module for mapping mime to rendering templates
22
+ # @author Bryan T. Meyers
23
+ module Renderer
15
24
 
16
- # Associate a MIME type to the current Renderer or Editor
17
- # @param [String] mime the MIME type
18
- # @return [void]
19
- def mime(mime)
20
- if $current_renderer
21
- $renderers[mime] = $current_renderer
22
- $templates[$current_renderer] = $current_template
23
- end
24
- if $current_editor
25
- $editors[mime] = $current_editor
26
- end
27
- end
25
+ # Callback for handling partials
26
+ # @param [Hash] conf the raw configuration
27
+ # @return [Hash] post-processed configuration
28
+ def self.configure_partial(conf)
29
+ conf['partial'] = Tilt.new(conf['partial'], 1, { ugly: true })
30
+ conf
31
+ end
28
32
 
29
- # Setup a new template
30
- # @param [String] template the template for a renderer or editor
31
- # @return [void]
32
- def partial(template)
33
- $current_template = Tilt.new(template, 1, { ugly: true })
34
- end
33
+ # Callback for handling templates
34
+ # @param [Hash] conf the raw configuration
35
+ # @return [Hash] post-processed configuration
36
+ def self.configure_template(conf)
37
+ conf['partial'] = Tilt.new(conf['file'], 1, { ugly: true })
38
+ conf
39
+ end
35
40
 
36
- # Setup an Editor
37
- # @param [Class] editor the template for this Editor
38
- # @param [Proc] block for configuring this Editor
39
- # @return [void]
40
- def editor(editor, &block)
41
- $current_editor = Tilt.new(editor, 1, { ugly: true })
42
- $current_renderer = nil
43
- Docile.dsl_eval(self, &block)
44
- end
45
- end
41
+ # Read all of the configs in './configs/apps'
42
+ # @return [void]
43
+ def self.read_configs
44
+ $wire_editors = Wire::Config.read_config_dir('config/editors', method(:configure_partial))
45
+ $wire_renderers = Wire::Config.read_config_dir('config/renderers', method(:configure_partial))
46
+ $wire_templates = Wire::Config.read_config_dir('config/templates', method(:configure_template))
47
+ end
48
+ end
46
49
  end