wire-framework 0.1.0

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.
data/lib/closet.rb ADDED
@@ -0,0 +1,99 @@
1
+ require 'rack'
2
+ require_relative 'app'
3
+ require_relative 'closet/auth'
4
+ require_relative 'closet/context'
5
+ require_relative 'closet/resource'
6
+ require_relative 'closet/renderer'
7
+
8
+
9
+ module Wire
10
+ # A Closet is a configured Wire Environment
11
+ # @author Bryan T. Meyers
12
+ class Closet
13
+ include Wire::App
14
+ include Wire::Auth
15
+ include Wire::Renderer
16
+ include Wire::Resource
17
+
18
+ # Create an empty Closet
19
+ # @return [Wire::Closet] the new closet
20
+ def initialize
21
+ $apps = {}
22
+ $editors = {}
23
+ $renderers = {}
24
+ $templates = {}
25
+ end
26
+
27
+ # Route a Request to the correct Wire::App
28
+ # @param [Wire::Context] context the context of this Request
29
+ # @return [Response] a Rack Response triplet, or status code
30
+ def route(context)
31
+ actions = actions_allowed(context)
32
+ if actions.include? context.action
33
+ context.type.invoke(actions, context)
34
+ else
35
+ 401
36
+ end
37
+ end
38
+
39
+ # Fulfill the current request
40
+ # @param [Hash] env the Rack environment
41
+ # @return [Response] a Rack Response triplet, or status code
42
+ def call(env)
43
+ begin
44
+ context = Wire::Context.new(env)
45
+ response = route(context)
46
+ rescue Exception => e
47
+ [400, {}, e.message]
48
+ end
49
+ if response.is_a? Array
50
+ if response[2]
51
+ unless response[2].is_a? Array
52
+ response[2] = [response[2]]
53
+ end
54
+ end
55
+ else
56
+ if response.is_a? Integer
57
+ response = [response, {}, []]
58
+ else
59
+ response = [200, {}, [response]]
60
+ end
61
+ end
62
+ response
63
+ end
64
+
65
+ # A factory method for configuring a Closet
66
+ # @param [Proc] block the configuration routine
67
+ # @return [Wire::Closet] the configured Closet
68
+ def self.build(&block)
69
+ closet = Wire::Closet.new
70
+ puts 'Starting Up Wire...'
71
+ puts 'Starting Apps...'
72
+ Docile.dsl_eval(closet, &block)
73
+ closet.info
74
+ closet
75
+ end
76
+
77
+ # Print out a human-readable configuration
78
+ # @return [void]
79
+ def info
80
+ puts "Apps:\n"
81
+ $apps.each do |app, config|
82
+ puts "\u{2502}"
83
+ puts "\u{251c} Name: #{app}"
84
+ if config[:auth]
85
+ puts "\u{2502}\t\u{251c} Auth:"
86
+ if config[:auth][:level] == :app
87
+ puts "\u{2502}\t\u{2502}\t\u{251c} Level:\t#{config[:auth][:level]}"
88
+ puts "\u{2502}\t\u{2502}\t\u{2514} Handler:\t#{config[:auth][:handler]}"
89
+ else
90
+ puts "\u{2502}\t\u{2502}\t\u{2514} Level:\t#{config[:auth][:level]}"
91
+ end
92
+ end
93
+ if config[:type]
94
+ puts "\u{2502}\t\u{2514} Type: #{config[:type]}"
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,55 @@
1
+
2
+ module Wire
3
+ # Auth is a module for handling authorization
4
+ # @author Bryan T. Meyers
5
+ module Auth
6
+
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 :user
23
+ if user == auth[:user]
24
+ actions = [:create, :read, :readAll, :update, :delete]
25
+ end
26
+ end
27
+ end
28
+ actions
29
+ end
30
+
31
+ # Setup auth for an App
32
+ # @param [Symbol] level the type of authz to perform
33
+ # @param [Proc] block setup for the authz
34
+ # @return [void]
35
+ def auth(level, &block)
36
+ $current_app[:auth] = { level: level }
37
+ unless (level == :any) || (block.nil?)
38
+ Docile.dsl_eval(self, &block)
39
+ end
40
+ end
41
+
42
+ # Select handler for :app level of auth
43
+ # @param [Module] handler the type of authz to perform
44
+ # @return [void]
45
+ def handler(handler)
46
+ $current_app[:auth][:handler] = handler
47
+ end
48
+
49
+ # Select user for :user level of auth
50
+ # @return [void]
51
+ def user(user)
52
+ $current_app[:auth][:user] = user
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,103 @@
1
+ module Wire
2
+ # Context is a class containing request information
3
+ # @author Bryan T. Meyers
4
+
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
32
+
33
+ attr_reader :action, :app, :body, :env, :json, :query,
34
+ :query_string, :referer, :resource, :type,
35
+ :uri, :user, :verb
36
+
37
+ # Maps HTTP verbs to actions
38
+ HTTP_ACTIONS = {
39
+ 'GET' => :read,
40
+ 'HEAD' => :read,
41
+ 'POST' => :create,
42
+ 'PUT' => :update,
43
+ 'DELETE' => :delete
44
+ }
45
+
46
+ # Maps HTTP verbs to Symbols
47
+ HTTP_VERBS = {
48
+ 'GET' => :get,
49
+ 'HEAD' => :head,
50
+ 'POST' => :post,
51
+ 'PUT' => :put,
52
+ 'DELETE' => :delete
53
+ }
54
+
55
+ # Add user info to session
56
+ # @param [Hash] env the Rack environment
57
+ # @return [Hash] the updated environment
58
+ def update_session(env)
59
+ user = env['HTTP_REMOTE_USER']
60
+ user = user ? user : 'nobody'
61
+ env['rack.session'][:user] = user
62
+ env
63
+ end
64
+
65
+ # Builds a new Context
66
+ # @param [Hash] env the Rack environment
67
+ # @return [Context] a new Context
68
+ def initialize(env)
69
+ @env = update_session(env)
70
+ @user = env['rack.session'][:user]
71
+ @verb = HTTP_VERBS[env['REQUEST_METHOD']]
72
+ @action = HTTP_ACTIONS[env['REQUEST_METHOD']]
73
+ if env['HTTP_REFERER']
74
+ @referer = env['HTTP_REFERER'].split('/')
75
+ else
76
+ @referer = []
77
+ end
78
+ @uri = env['REQUEST_URI'].split('?')[0].split('/')
79
+ app = $apps[@uri[1]]
80
+ if app
81
+ @app = app
82
+ @resource = app[:resources][@uri[2]]
83
+ @type = app[:type]
84
+ else
85
+ throw Exception.new("App: #{@uri[1]} is Undefined")
86
+ end
87
+ @query = {}
88
+ env['QUERY_STRING'].split('&').each do |q|
89
+ param = q.split('=')
90
+ @query[param[0].to_sym] = param[1]
91
+ end
92
+ @query_string = env['QUERY_STRING']
93
+ if env['rack.input']
94
+ @body = env['rack.input'].read
95
+ begin
96
+ @json = JSON.parse_clean(@body)
97
+ rescue JSON::ParserError
98
+ $stderr.puts 'Warning: Failed to parse body as JSON'
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,46 @@
1
+ module Wire
2
+ # Renderer is a module for mapping mime to rendering templates
3
+ # @author Bryan T. Meyers
4
+ module Renderer
5
+
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
15
+
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
28
+
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
35
+
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
46
+ end
@@ -0,0 +1,18 @@
1
+ module Wire
2
+
3
+ # Resource is a DSL function for mapping sub-URI in Wire::App(s)
4
+ # @author Bryan T. Meyers
5
+ module Resource
6
+
7
+ # Setup a Renderer
8
+ # @param [String] uri the sub-URI
9
+ # @param [Proc] block for configuring this resource
10
+ # @return [void]
11
+ def resource(uri, &block)
12
+ $current_app[:resources][uri] = {}
13
+ $current_resource = $current_app[:resources][uri]
14
+ puts "Starting Resource At: /#{$current_uri + '/' + uri}"
15
+ Docile.dsl_eval(self, &block)
16
+ end
17
+ end
18
+ end
data/lib/wire.rb ADDED
@@ -0,0 +1,28 @@
1
+ $environment = {} unless $environment
2
+
3
+ require_relative 'closet'
4
+ require_relative 'app'
5
+
6
+ require 'docile'
7
+ require 'json'
8
+ require 'rack'
9
+
10
+ # The Ruby-Core JSON module
11
+ module JSON
12
+
13
+ # Force JSON.parse to symbolize names
14
+ # @param [String] source the raw JSON string
15
+ # @param [Hash] opts any further options for JSON.parse
16
+ # @return [Hash] the parsed JSON content
17
+ def self.parse_clean(source, opts = {})
18
+ opts[:symbolize_names] = true
19
+ parse(source, opts)
20
+ end
21
+ end
22
+
23
+ # Wire is an environment for quickly building REST services
24
+ # @author Bryan T. Meyers
25
+ module Wire
26
+ # Current version of the Wire Gem
27
+ VERSION = '0.1.0'
28
+ end
metadata ADDED
@@ -0,0 +1,208 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wire-framework
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Bryan T. Meyers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: awesome_print
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: cobravsmongoose
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: data_mapper
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: docile
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: nokogiri
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: nori
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rack
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rest-client
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: tilt
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: wiki-this
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :runtime
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: Wire is a DSL and Rack interface for quickly building web applications,
154
+ without the needless complexity of Rails
155
+ email: bmeyers@datadrake.com
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - LICENSE
161
+ - README.md
162
+ - lib/app.rb
163
+ - lib/app/db.rb
164
+ - lib/app/file.rb
165
+ - lib/app/history.rb
166
+ - lib/app/history/svn.rb
167
+ - lib/app/login.rb
168
+ - lib/app/render.rb
169
+ - lib/app/render/document.rb
170
+ - lib/app/render/editor.rb
171
+ - lib/app/render/instant.rb
172
+ - lib/app/render/page.rb
173
+ - lib/app/render/partial.rb
174
+ - lib/app/render/style.rb
175
+ - lib/app/repo.rb
176
+ - lib/app/repo/svn.rb
177
+ - lib/closet.rb
178
+ - lib/closet/auth.rb
179
+ - lib/closet/context.rb
180
+ - lib/closet/renderer.rb
181
+ - lib/closet/resource.rb
182
+ - lib/wire.rb
183
+ homepage: http://rubygems.org/gems/wire
184
+ licenses:
185
+ - GPL v2
186
+ metadata: {}
187
+ post_install_message:
188
+ rdoc_options: []
189
+ require_paths:
190
+ - lib
191
+ required_ruby_version: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ required_rubygems_version: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ requirements: []
202
+ rubyforge_project:
203
+ rubygems_version: 2.2.2
204
+ signing_key:
205
+ specification_version: 4
206
+ summary: Wire Framework
207
+ test_files: []
208
+ has_rdoc: