roy 0.5.2 → 0.5.3

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.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- roy (0.5.2)
4
+ roy (0.5.3)
5
5
  rack
6
6
 
7
7
  GEM
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2011 François "madx" Vaux <madx@yapok.org>
1
+ Copyright (c) 2009-2012 François "madx" Vaux <madx@yapok.org>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
@@ -1,4 +1,30 @@
1
1
  module Roy
2
+ # This module allows you to modify the response before it is sent to the
3
+ # client. It does this by overriding the {Roy#call} method.
4
+ #
5
+ # == Configuration:
6
+ # roy.conf.after::
7
+ # A proc object that will be called with the response as argument.
8
+ # Defaults to identity if not set.
9
+ #
10
+ # @example Forcing a custom content-type
11
+ #
12
+ # class SetContentType
13
+ # include Roy
14
+ #
15
+ # roy use: [:after],
16
+ # after: ->(resp) { resp.headers['Content-Type'] = 'text/x-foo' }
17
+ #
18
+ # def get(_)
19
+ # "Hello, world\n"
20
+ # end
21
+ # end
22
+ #
23
+ # @example Demo
24
+ #
25
+ # $ curl -i localhost:9292
26
+ # HTTP/1.1 200 OK
27
+ # Content-Type: text/x-foo
2
28
  module After
3
29
  def call(env)
4
30
  status, header, body = super
@@ -9,17 +9,23 @@ require 'ostruct'
9
9
  require 'roy/version'
10
10
  require 'roy/context'
11
11
 
12
+ # This is the main module that applications should include.
12
13
  module Roy
14
+
15
+ # Default options.
13
16
  Defaults = {allow: [:get], prefix: :'', use: [:halt]}
14
17
 
18
+ # Extend the class with the ClassMethods module.
15
19
  def self.included(base)
16
20
  base.send(:extend, ClassMethods)
17
21
  end
18
22
 
23
+ # Returns the application context or initialize it
19
24
  def roy
20
25
  @roy ||= Context.new(self)
21
26
  end
22
27
 
28
+ # A Rack-compliant #call method.
23
29
  def call(env)
24
30
  roy.prepare!(env)
25
31
 
@@ -41,6 +47,7 @@ module Roy
41
47
  module ClassMethods
42
48
  attr_reader :conf
43
49
 
50
+ # Setup default configuration for the application.
44
51
  def self.extended(base)
45
52
  base.instance_eval do
46
53
  @conf ||= OpenStruct.new
@@ -48,6 +55,7 @@ module Roy
48
55
  end
49
56
  end
50
57
 
58
+ # Set options for the application
51
59
  def roy(options={})
52
60
  options.each do |key,value|
53
61
  case key
@@ -1,20 +1,76 @@
1
1
  module Roy
2
+ # This module provides helpers for using the HTTP basic authentication system.
3
+ #
4
+ # == Configuration:
5
+ # roy.conf.auth [:realm]::
6
+ # The authentication realm to use.
7
+ # roy.conf.auth [:logic]::
8
+ # A proc that checks if an user is authorized. See #authorized? in
9
+ # InstanceMethods.
10
+ #
11
+ # @example Simple auth example
12
+ #
13
+ # class AuthApp
14
+ # include Roy
15
+ # roy use: [:basic_auth],
16
+ # auth: {
17
+ # realm: "My Realm",
18
+ # logic: ->(_, u, p) { %w(admin foobar) == [u, p] }
19
+ # }
20
+ #
21
+ # def get(_)
22
+ # roy.protected!
23
+ # "Protected zone"
24
+ # end
25
+ # end
26
+ #
27
+ # @example Using user data
28
+ #
29
+ # class AuthUserDataApp
30
+ # include Roy
31
+ # roy use: [:basic_auth],
32
+ # auth: {
33
+ # realm: "My Realm",
34
+ # logic: ->(override, u, p) {
35
+ # override || (%w(admin foobar) == [u, p])
36
+ # }
37
+ # }
38
+ #
39
+ # def get(path)
40
+ # roy.protected!(path =~ /private/)
41
+ # "Protected if path contains private"
42
+ # end
43
+ # end
2
44
  module BasicAuth
3
- def protected!(data=nil)
4
- unless authorized?(data)
5
- realm = roy.conf.auth && roy.conf.auth[:realm] || 'Realm'
6
- roy.response['WWW-Authenticate'] = %(Basic realm="#{realm}")
7
- roy.halt 401
8
- end
45
+ def self.setup(roy)
46
+ roy.send(:extend, InstanceMethods)
9
47
  end
10
48
 
11
- def authorized?(data=nil)
12
- auth = Rack::Auth::Basic::Request.new(roy.request.env)
49
+ module InstanceMethods
50
+
51
+ # Protect all subsequent code using HTTP Basic Authentication.
52
+ #
53
+ # @param data user data to pass to #authorized?
54
+ def protected!(data=nil)
55
+ unless authorized?(data)
56
+ realm = conf.auth && conf.auth[:realm] || 'Realm'
57
+ response['WWW-Authenticate'] = %(Basic realm="#{realm}")
58
+ halt 401
59
+ end
60
+ end
13
61
 
14
- auth.provided? && auth.basic? && auth.credentials &&
15
- (roy.conf.auth[:logic] || ->(data, u, p) {
16
- %w(admin password) == [u, p]
17
- }).(data, *auth.credentials)
62
+ # Runs the authentication logic against the user and passord given in the
63
+ # request, using custom additional data.
64
+ #
65
+ # @param data user data to pass to the authentication logic
66
+ def authorized?(data=nil)
67
+ auth = Rack::Auth::Basic::Request.new(request.env)
68
+
69
+ auth.provided? && auth.basic? && auth.credentials &&
70
+ (conf.auth[:logic] || ->(data, u, p) {
71
+ %w(admin password) == [u, p]
72
+ }).(data, *auth.credentials)
73
+ end
18
74
  end
19
75
  end
20
76
  end
@@ -1,4 +1,33 @@
1
1
  module Roy
2
+ # This module allows you to modify the environment before it is handled by the
3
+ # application. It does this by overriding the {Roy#call} method.
4
+ #
5
+ # == Configuration:
6
+ # roy.conf.before::
7
+ # A proc object that will be called with the environment as argument.
8
+ # Defaults to identity if not set.
9
+ #
10
+ # @example Forcing a method
11
+ #
12
+ # class AlwaysGet
13
+ # include Roy
14
+ #
15
+ # roy allow: [:put, :post], use: [:before],
16
+ # before: ->(env) { env['REQUEST_METHOD'] = 'GET' }
17
+ #
18
+ # def get(_)
19
+ # "Hello, world\n"
20
+ # end
21
+ # end
22
+ #
23
+ # @example Demo
24
+ #
25
+ # $ curl -i localhost:9292
26
+ # HTTP/1.1 200 OK
27
+ # $ curl -X POST -i localhost:9292
28
+ # HTTP/1.1 200 OK
29
+ # $ curl -X PUT -i localhost:9292
30
+ # HTTP/1.1 200 OK
2
31
  module Before
3
32
  def call(env)
4
33
  (roy.conf.before || lambda {|x| x }).(env)
@@ -1,7 +1,33 @@
1
1
  module Roy
2
+ # Application context for Roy applications.
3
+ #
4
+ # Everything must be namespaced in this context to avoid any clashes and to
5
+ # make the code cleaner.
2
6
  class Context
3
- attr_reader :app, :conf, :env, :request, :response, :headers, :params
7
+ # Returns the current application
8
+ attr_reader :app
4
9
 
10
+ # Returns the application's configuration
11
+ attr_reader :conf
12
+
13
+ # Returns the environment passed to #call
14
+ attr_reader :env
15
+
16
+ # Returns the current request
17
+ attr_reader :request
18
+
19
+ # Returns the current response
20
+ attr_reader :response
21
+
22
+ # Returns the current response's headers
23
+ attr_reader :headers
24
+
25
+ # Returns the current request's params
26
+ attr_reader :params
27
+
28
+ # Creates a new Context object.
29
+ #
30
+ # @param app the context's application
5
31
  def initialize(app)
6
32
  @app = app
7
33
  @conf = app.class.conf
@@ -11,6 +37,9 @@ module Roy
11
37
  end
12
38
  end
13
39
 
40
+ # Initializes the attributes based on an environment.
41
+ #
42
+ # @param env the environment to use
14
43
  def prepare!(env)
15
44
  @env = env
16
45
  @request = Rack::Request.new(env)
@@ -1,11 +1,38 @@
1
1
  module Roy
2
+ # This module adds a +halt+ method to the application context that allows you
3
+ # to break during a handler and immediately return a status code and a body.
4
+ #
5
+ # Included by default.
6
+ #
7
+ # @example A Not Found application
8
+ #
9
+ # class NotFoundApp
10
+ # include Roy
11
+ #
12
+ # def get(_)
13
+ # halt 404
14
+ # end
15
+ # end
16
+ #
17
+ # @example Test
18
+ #
19
+ # $ curl -i localhost:9292
20
+ # HTTP/1.1 404 Not Found
2
21
  module Halt
3
22
 
4
23
  def self.setup(roy)
5
- class << roy
6
- def halt(code, message=nil)
7
- throw :halt, [code, message || Rack::Utils::HTTP_STATUS_CODES[code]]
8
- end
24
+ roy.send(:extend, InstanceMethods)
25
+ end
26
+
27
+ module InstanceMethods
28
+ # Break from the current +catch(:halt)+ block
29
+ #
30
+ # @param [Integer] code the response status code.
31
+ # @param [String] message the response body.
32
+ # @return [Integer, String] the status and the given message or a default
33
+ # one.
34
+ def halt(code, message=nil)
35
+ throw :halt, [code, message || Rack::Utils::HTTP_STATUS_CODES[code]]
9
36
  end
10
37
  end
11
38
 
@@ -1,24 +1,99 @@
1
1
  require 'tilt'
2
2
 
3
3
  module Roy
4
+ # A simple template rendering mechanism based on Tilt.
5
+ #
6
+ # == Configuration:
7
+ # roy.conf.render::
8
+ # A hash of options to pass to Tilt.
9
+ # roy.conf.views::
10
+ # The directory where views are kept. Defaults to +views/+
11
+ #
12
+ # @example Using <tt>roy.render</tt>
13
+ #
14
+ # class ErbApp
15
+ # include Roy
16
+ #
17
+ # roy use: [:render]
18
+ #
19
+ # def get(path)
20
+ # case path
21
+ # when /\/hello/
22
+ # roy.render :erb, "Hello, <%= roy.params[:p] || \"world\" %>!\n"
23
+ # else
24
+ # roy.render :erb, :index
25
+ # end
26
+ # end
27
+ # end
28
+ #
29
+ # @example Test
30
+ #
31
+ # $ cat views/index.erb
32
+ # Let me <a href="/hello">greet</a> you.
33
+ # $ curl -i localhost:9292
34
+ # Let me <a href="/hello">greet</a> you.
35
+ # $ curl -i localhost:9292/hello?p=blah
36
+ # Hello, blah!
37
+ #
38
+ # @example Haml renderer with partials support
39
+ #
40
+ # module HamlRenderWithPartial
41
+ # def self.setup(roy)
42
+ # roy.send(:extend, InstanceMethods)
43
+ # end
44
+ #
45
+ # module InstanceMethods
46
+ # def render(tpl_or_string, params={})
47
+ # case layout = params.delete(:layout)
48
+ # when false
49
+ # super(:haml, tpl_or_string, params)
50
+ # else
51
+ # super(:haml, :layout, params do
52
+ # super(:haml, tpl_or_string, params)
53
+ # end
54
+ # end
55
+ # end
56
+ # end
57
+ # end
4
58
  module Render
5
59
 
6
60
  def self.setup(roy)
7
- class << roy
8
- def render(engine, view_or_string, params={}, &block)
9
- options = conf.render || {}
10
- template = case view_or_string
11
- when Symbol
12
- file = [view_or_string.to_s, engine].map(&:to_s).join('.')
13
- dir = conf.views || 'views'
14
- Tilt.new(File.join(dir, file), nil, options)
15
- else
16
- Tilt[engine].new(nil, nil, options) { view_or_string.to_s }
17
- end
61
+ roy.send(:extend, InstanceMethods)
62
+ end
63
+
64
+ module InstanceMethods
18
65
 
19
- template.render(app, params, &block)
20
- end
66
+ # Render the given template or string with the selected engine.
67
+ #
68
+ # Views are looked for inside the +roy.conf.views+ directory.
69
+ # Files should have an extension matching the selected engine.
70
+ # If you want to use sub-directories, you have to use the
71
+ # +:"subdir/file.ext"+ syntax.
72
+ #
73
+ # @see https://github.com/rtomayko/tilt/blob/master/README.md
74
+ # @see https://github.com/rtomayko/tilt/blob/master/TEMPLATES.md
75
+ #
76
+ # @param [Symbol] engine the name of the rendering engine. Must be
77
+ # supported by Tilt.
78
+ # @param [Symbol] view_or_string a template file.
79
+ # @param [String] view_or_string a template string.
80
+ # @param [Hash] params locals for Tilt::Template#render.
81
+ # @param [Proc] block a block to execute when using +yield+ in the
82
+ # template.
83
+ def render(engine, view_or_string, params={}, &block)
84
+ options = conf.render || {}
85
+ template = case view_or_string
86
+ when Symbol
87
+ file = [view_or_string.to_s, engine].map(&:to_s).join('.')
88
+ dir = conf.views || 'views'
89
+ Tilt.new(File.join(dir, file), nil, options)
90
+ else
91
+ Tilt[engine].new(nil, nil, options) { view_or_string.to_s }
92
+ end
93
+
94
+ template.render(app, params, &block)
21
95
  end
96
+
22
97
  end
23
98
 
24
99
  end
@@ -1,6 +1,8 @@
1
1
  module Roy
2
- VERSION = [0, 5, 2]
2
+ # Roy version
3
+ VERSION = [0, 5, 3]
3
4
 
5
+ # Return the version as a String.
4
6
  def self.version
5
7
  VERSION.join('.')
6
8
  end
@@ -10,7 +10,7 @@ class BasicAuthTestObject
10
10
  }
11
11
 
12
12
  def get(path)
13
- protected!
13
+ roy.protected!
14
14
  'success'
15
15
  end
16
16
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-17 00:00:00.000000000 Z
12
+ date: 2012-02-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
- requirement: &19255820 !ruby/object:Gem::Requirement
16
+ requirement: &13775240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *19255820
24
+ version_requirements: *13775240
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: minitest
27
- requirement: &19255280 !ruby/object:Gem::Requirement
27
+ requirement: &13774520 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *19255280
35
+ version_requirements: *13774520
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rack-test
38
- requirement: &19254660 !ruby/object:Gem::Requirement
38
+ requirement: &13792140 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *19254660
46
+ version_requirements: *13792140
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: tilt
49
- requirement: &19254220 !ruby/object:Gem::Requirement
49
+ requirement: &13791400 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *19254220
57
+ version_requirements: *13791400
58
58
  description: ! 'roy is a small library which allows every Ruby object to be used
59
59
 
60
60
  as a Rack application.'
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
111
  version: '0'
112
112
  requirements: []
113
113
  rubyforge_project: roy
114
- rubygems_version: 1.8.5
114
+ rubygems_version: 1.8.15
115
115
  signing_key:
116
116
  specification_version: 3
117
117
  summary: make your objects REST-friendly