cuba-api 0.6.1 → 0.6.2

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 08d01480616570cd7a09d1f5da7a869037be9c2c
4
+ data.tar.gz: 6ef17555b198ffac42def04e185ad4033706d4aa
5
+ SHA512:
6
+ metadata.gz: 5a71e0b5d9b846a001f6d8d74c723bc9eab62033e82ba7f19dbbb0073d6c8fd2ea2967994578679757db2ef76867cf8b2dfb5e57c078a49f5f20b774ec9243cd
7
+ data.tar.gz: 901b16bf0da46243f5007eae69178d4adb84862a17dd2b92654f56891d3ecd6a860b042e98c993439fad92f276e53f60fd35c87a8314375d5fc163a7038c59c7
@@ -21,23 +21,21 @@
21
21
  # -*- Coding: utf-8 -*-
22
22
  require "cuba"
23
23
 
24
- require 'cuba_api/write_aspect'
25
- require 'cuba_api/serializer'
26
- require 'cuba_api/current_user'
27
- require 'cuba_api/guard'
28
- require 'cuba_api/accept_content'
24
+ require 'cuba_api/aspects'
25
+ require 'cuba_api/aspects/serializer'
26
+ require 'cuba_api/aspects/accept_content'
29
27
  require 'cuba_api/config'
28
+ require 'cuba_api/loggers'
30
29
  require 'cuba_api/input_filter'
31
- require 'cuba_api/response_status'
30
+ require 'cuba_api/aspects/response_status'
32
31
 
33
32
  class CubaAPI < Cuba
34
33
 
35
34
  plugin CubaApi::Config
36
- plugin CubaApi::WriteAspect
35
+ plugin CubaApi::Loggers
36
+ plugin CubaApi::Aspects
37
37
  plugin CubaApi::Serializer
38
38
  plugin CubaApi::AcceptContent
39
- plugin CubaApi::CurrentUser
40
- plugin CubaApi::Guard
41
39
  plugin CubaApi::InputFilter
42
40
  plugin CubaApi::ResponseStatus
43
41
 
@@ -0,0 +1,58 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ # -*- Coding: utf-8 -*-
22
+
23
+ module CubaApi
24
+ module Aspects
25
+
26
+ module ClassMethods
27
+ def append_aspect( arg )
28
+ aspects << arg
29
+ aspects_logger.info { "Appended #{arg}" }
30
+ end
31
+
32
+ def prepend_aspect( arg )
33
+ aspects.insert( 0, arg )
34
+ aspects_logger.info { "Prepended #{arg}" }
35
+ end
36
+
37
+ def aspects
38
+ self[ :aspects ] ||= []
39
+ end
40
+
41
+ private
42
+
43
+ def aspects_logger
44
+ logger_factory.logger( 'CubaAPI::Aspects' )
45
+ end
46
+ end
47
+
48
+ def write( obj, options = {} )
49
+ self.res.status = options[:status] || 200
50
+ # make sure we inherit aspects and repsect the order
51
+ aspects = self.class[ :aspects ] # == CubaAPI ? [] : self.class.superclass[ :aspects ]
52
+ (aspects + self.class[ :aspects ]).uniq.each do |w|
53
+ obj = send( w, obj, options ) if obj
54
+ end
55
+ res.write obj.to_s
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,68 @@
1
+ #
2
+ # Copyright (C) 2012 Christian Meier
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy of
5
+ # this software and associated documentation files (the "Software"), to deal in
6
+ # the Software without restriction, including without limitation the rights to
7
+ # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8
+ # the Software, and to permit persons to whom the Software is furnished to do so,
9
+ # subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in all
12
+ # copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16
+ # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17
+ # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18
+ # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19
+ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ #
21
+ # -*- Coding: utf-8 -*-
22
+ module CubaApi
23
+ module AcceptContent
24
+
25
+ module ClassMethods
26
+
27
+ MIMES = { :yaml => ['application/x-yaml', 'text/yaml'],
28
+ :json => ['application/json'],
29
+ :xml => ['application/xml'] }
30
+
31
+ def accept( *args )
32
+ args.each do |arg|
33
+ (MIMES[ arg ] || []).each do |mime|
34
+ if arg == :yaml
35
+ require 'safe_yaml' unless defined?( YAML )
36
+ end
37
+ mimes[ mime ] = "to_#{arg}".to_sym
38
+ end
39
+ end
40
+ accept_logger.info { "Accept: #{mimes.keys.join(', ')}" }
41
+ end
42
+
43
+ def mimes
44
+ self[ :mimes ] ||= {}
45
+ end
46
+
47
+ def accept_logger
48
+ logger_factory.logger( "CubaApi::AcceptContent" )
49
+ end
50
+ end
51
+
52
+ def accept_content( obj, options = {} )
53
+ mime = env[ 'HTTP_ACCEPT' ]
54
+ if self.class.mimes.key?( mime )
55
+ res[ "Content-Type" ] = mime + "; charset=utf-8"
56
+ obj.send self.class[ :mimes ][ mime ]
57
+ else
58
+ self.class.accept_logger.debug { "'#{mime}' not in allowed list #{self.class[ :mimes ].keys.inspect}" }
59
+ no_body :not_found
60
+ nil
61
+ end
62
+ end
63
+
64
+ def self.included( base )
65
+ base.append_aspect :accept_content
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,54 @@
1
+ module CubaApi
2
+ module ResponseStatus
3
+ def response_status( obj, options = {})
4
+ if options[ :response_status ] == false
5
+ obj
6
+ else
7
+ handle_status( obj )
8
+ end
9
+ end
10
+
11
+ def self.included( base )
12
+ base.prepend_aspect :response_status
13
+ end
14
+
15
+ private
16
+
17
+ def handle_status( obj )
18
+ if obj.respond_to?( :errors ) && obj.errors.size > 0
19
+ res.status = 412 # Precondition Failed
20
+ log_errors( obj.errors )
21
+ obj.errors
22
+ elsif req.post?
23
+ res.status = 201 # Created
24
+ set_location( obj )
25
+ obj
26
+ elsif req.delete?
27
+ res.status = 204 # No Content
28
+ ''
29
+ else
30
+ obj
31
+ end
32
+ end
33
+
34
+ def set_location( obj )
35
+ if obj.respond_to?( :id ) && ! res[ 'Location' ]
36
+ res[ 'Location' ] = env[ 'SCRIPT_NAME' ].to_s + "/#{obj.id}"
37
+ end
38
+ end
39
+
40
+ def log_errors( errors )
41
+ status_logger.info do
42
+ if errors.respond_to? :to_hash
43
+ errors.to_hash.values.join( "\n" )
44
+ else
45
+ errors.inspect
46
+ end
47
+ end
48
+ end
49
+
50
+ def status_logger
51
+ logger_factory.logger( "CubaApi::ResponseStatus" )
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,56 @@
1
+ module CubaApi
2
+ module ResponseStatus
3
+ def response_statuss( obj, options = {})
4
+ if options[ :response_status ] == false
5
+ puts 'asd'
6
+ obj
7
+ else
8
+ puts 'dsa'
9
+ handle_status( obj )
10
+ end
11
+ end
12
+
13
+ def self.included( base )
14
+ base.prepend_aspect :response_status
15
+ end
16
+
17
+ private
18
+
19
+ def handle_status( obj )
20
+ if obj.respond_to?( :errors ) && obj.errors.size > 0
21
+ res.status = 412 # Precondition Failed
22
+ log_errors( obj.errors )
23
+ obj.errors
24
+ elsif req.post?
25
+ res.status = 201 # Created
26
+ set_location( obj )
27
+ obj
28
+ elsif req.delete?
29
+ res.status = 204 # No Content
30
+ ''
31
+ else
32
+ obj
33
+ end
34
+ end
35
+
36
+ def set_location( obj )
37
+ if obj.respond_to?( :id ) && ! res[ 'Location' ]
38
+ res[ 'Location' ] = env[ 'SCRIPT_NAME' ].to_s + "/#{obj.id}"
39
+ end
40
+ end
41
+
42
+ def log_errors( errors )
43
+ status_logger.info do
44
+ if errors.respond_to? :to_hash
45
+ errors.to_hash.values.join( "\n" )
46
+ else
47
+ errors.inspect
48
+ end
49
+ end
50
+ end
51
+
52
+ def status_logger
53
+ logger_factory.logger( "CubaApi::ResponseStatus" )
54
+ end
55
+ end
56
+ end
@@ -38,4 +38,4 @@ module CubaApi
38
38
  end
39
39
  end
40
40
  end
41
- end
41
+ end
@@ -163,6 +163,13 @@ module CubaApi
163
163
  end
164
164
 
165
165
  private
166
+
167
+ def _cors_allowed?( cors, methods )
168
+ ( methods != nil &&
169
+ methods.detect { |m| send m.to_sym } != nil ) ||
170
+ ( env[ 'HTTP_ORIGIN' ] &&
171
+ cors.origins( env[ 'HTTP_ORIGIN' ] ) != nil )
172
+ end
166
173
 
167
174
  def _on_cors( methods = nil, *args )
168
175
  cors = ( self.class[ :cors ] ||= CORS.new( self.class ) )
@@ -172,16 +179,7 @@ module CubaApi
172
179
  on *args do
173
180
  cors.process( env, res, methods )
174
181
  end
175
- else
176
- unless methods.nil?
177
- allowed = methods.detect do |m|
178
- send m.to_sym
179
- end
180
- args.insert( 0, allowed != nil )
181
- end
182
- if env[ 'HTTP_ORIGIN' ]
183
- args.insert( 0, cors.origins( env[ 'HTTP_ORIGIN' ] ) != nil )
184
- end
182
+ elsif _cors_allowed?( cors, methods ) != false # could be true or nil
185
183
  on *args do |*vars|
186
184
  cors.allow_origin( env, res )
187
185
  yield( *vars )
@@ -34,7 +34,7 @@ module CubaApi
34
34
  def guard( &block )
35
35
  self[ :guard ] ||= block ||
36
36
  begin
37
- warn 'no guard configured. default guard denies eveythings !'
37
+ guard_logger.warn { 'no guard configured. default guard denies everything !' }
38
38
  guard = Ixtlan::UserManagement::Guard.new
39
39
  Proc.new do |groups|
40
40
  guard
@@ -42,6 +42,9 @@ module CubaApi
42
42
  end
43
43
  end
44
44
 
45
+ def guard_logger
46
+ logger_factory.logger( "CubaApi::Guard" )
47
+ end
45
48
  end
46
49
 
47
50
  def current_groups
@@ -53,11 +56,7 @@ module CubaApi
53
56
  end
54
57
 
55
58
  def on_context( name, &block )
56
- perm = guard.permissions( name )
57
- if perm && perm.parent &&
58
- perm.parent.resource != guard_context
59
- raise 'parent resource is not guarded'
60
- end
59
+ guard.check_parent( name, guard_context )
61
60
  on name do
62
61
  begin
63
62
  old = guard_context
@@ -71,9 +70,7 @@ module CubaApi
71
70
 
72
71
  def on_association
73
72
  on :association do |association|
74
- # TODO one method in guard
75
- asso = guard.permissions( guard_context ).associations
76
- if asso.empty? or asso.include?( association )
73
+ if allowed_associations && allowed_associations.include?( association )
77
74
  yield( association )
78
75
  else
79
76
  no_body :forbidden
@@ -87,9 +84,11 @@ module CubaApi
87
84
 
88
85
  @_method = method
89
86
 
90
- warn "[CubaApi::Guard] check #{method.to_s.upcase} #{guard_context}: #{guard.allow?( guard_context, method )}"
87
+ allowed = allowed( method )
88
+
89
+ guard_logger.debug { "check #{method.to_s.upcase} #{guard_context}: #{allowed}" }
91
90
  # TODO guard needs no association here
92
- if guard.allow?( guard_context, method, (allowed_associations || []).first )
91
+ if allowed
93
92
 
94
93
  yield( *captures )
95
94
  else
@@ -100,9 +99,19 @@ module CubaApi
100
99
 
101
100
  private
102
101
 
102
+ def allowed( method )
103
+ if allowed_associations && !allowed_associations.empty?
104
+ allowed_associations.select do |asso|
105
+ guard.allow?( guard_context, method, asso )
106
+ end.size > 0
107
+ else
108
+ guard.allow?( guard_context, method )
109
+ end
110
+ end
111
+
103
112
  def guard_context( ctx = nil )
104
113
  if ctx
105
- @_conetxt = (req.env[ 'guard_context' ] = ctx)
114
+ @_context = (req.env[ 'guard_context' ] = ctx)
106
115
  else
107
116
  @_context ||= req.env[ 'guard_context' ]
108
117
  end
@@ -112,5 +121,8 @@ module CubaApi
112
121
  self.class.guard.call( current_groups )
113
122
  end
114
123
 
124
+ def guard_logger
125
+ self.class.guard_logger
126
+ end
115
127
  end
116
128
  end
@@ -0,0 +1,24 @@
1
+ module CubaApi
2
+ class Logger
3
+
4
+ private
5
+
6
+ def debug( msg = nil )
7
+ puts ( msg || yield )
8
+ end
9
+
10
+ def info( msg = nil )
11
+ puts ( msg || yield )
12
+ end
13
+
14
+ def warn( msg = nil )
15
+ warn ( msg || yield )
16
+ end
17
+
18
+ def error( msg = nil )
19
+ warn ( msg || yield )
20
+ end
21
+
22
+
23
+ end
24
+ end
@@ -0,0 +1,77 @@
1
+ module CubaApi
2
+
3
+ module Loggers
4
+ module ClassMethods
5
+
6
+ def logger_factory
7
+ self[ :loggers ] ||= CubaApi::LoggerFactory.new
8
+ end
9
+
10
+ end
11
+
12
+ def logger_factory
13
+ self.class.logger_factory
14
+ end
15
+ end
16
+
17
+ class LoggerFactory
18
+
19
+ def self.level=( level )
20
+ @level = level
21
+ end
22
+
23
+ def self.logger( cat )
24
+ loggers[ cat ] ||= Logger.new( cat, @level )
25
+ end
26
+
27
+ def logger( cat )
28
+ self.class.logger( cat )
29
+ end
30
+
31
+ private
32
+
33
+ def self.loggers
34
+ @loggers ||= {}
35
+ end
36
+ end
37
+
38
+ class Logger
39
+
40
+ private
41
+
42
+ def do_puts( level, &block )
43
+ if level >= @level
44
+ puts( "[#{@cat}] #{block.call}" )
45
+ end
46
+ end
47
+
48
+ def do_warn( level, &block )
49
+ if level >= @level
50
+ puts( "[#{@cat}] #{block.call}" )
51
+ end
52
+ end
53
+
54
+ public
55
+
56
+ def initialize( cat = 'ROOT', level = 1 )
57
+ @level = ( level || 1 ).to_i
58
+ @cat = cat
59
+ end
60
+
61
+ def debug( &block )
62
+ do_puts( 0, &block )
63
+ end
64
+
65
+ def info( &block )
66
+ do_puts( 1, &block )
67
+ end
68
+
69
+ def warn( &block )
70
+ do_warn( 2, &block )
71
+ end
72
+
73
+ def error( &block )
74
+ do_warn( 3, &block )
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,73 @@
1
+ module CubaApi
2
+
3
+ module Loggers
4
+ module ClassMethods
5
+
6
+ def logger_factory
7
+ self[ :loggers ] ||= CubaApi::LoggerFactory.new
8
+ end
9
+
10
+ end
11
+
12
+ def logger_factory
13
+ self.class.logger_factory
14
+ end
15
+ end
16
+
17
+ class LoggerFactory
18
+
19
+ def self.level=( level )
20
+ @level = level
21
+ end
22
+
23
+ def self.logger( cat )
24
+ loggers[ cat ] ||= Logger.new( cat, @level )
25
+ end
26
+
27
+ private
28
+
29
+ def self.loggers
30
+ @loggers ||= {}
31
+ end
32
+ end
33
+
34
+ class Logger
35
+
36
+ private
37
+
38
+ def puts( level, &block )
39
+ if level >= @level
40
+ Kernel.puts( "#{@cat} #{block.call}" )
41
+ end
42
+ end
43
+
44
+ def warn( level, &block )
45
+ if level >= @level
46
+ Kernel.puts( "#{@cat} #{block.call}" )
47
+ end
48
+ end
49
+
50
+ public
51
+
52
+ def initialize( cat = 'ROOT', level = 1 )
53
+ @level = ( level || 1 ).to_i
54
+ @cat = cat
55
+ end
56
+
57
+ def debug( &block )
58
+ puts ( 0, &block )
59
+ end
60
+
61
+ def info( &block )
62
+ puts ( 1, &block )
63
+ end
64
+
65
+ def warn( &block )
66
+ warn ( 2, &block )
67
+ end
68
+
69
+ def error( &block )
70
+ warn ( 3, &block )
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,18 @@
1
+ module CubaApi
2
+ module Rack
3
+ class AllowSessionRack
4
+ def initialize( app, *not_pattern )
5
+ @app = app
6
+ @regexp = /^\/#{not_pattern.join( '|^\/' )}/
7
+ end
8
+
9
+ def call( env )
10
+ status, headers, resp = @app.call( env )
11
+ if not( env[ 'PATH_INFO' ].match @regexp )
12
+ headers.delete( 'Set-Cookie' )
13
+ end
14
+ [ status, headers, resp ]
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ module CubaApi
2
+ module Rack
3
+ class Ext2MimeRack
4
+ def initialize( app, *allowed)
5
+ @app = app
6
+ @allowed = allowed
7
+ end
8
+
9
+ def call(env)
10
+ ext = env[ 'PATH_INFO' ].sub( /.*\./, '' )
11
+ if ext && @allowed.member?( ext )
12
+ mime = ::Rack::Mime.mime_type( '.' + ext )
13
+ env[ 'PATH_INFO_ORIG' ] = env[ 'PATH_INFO' ].dup
14
+ env[ 'HTTP_ACCEPT' ] = mime
15
+ env[ 'PATH_INFO' ].sub!( /\..*/, '' )
16
+ end
17
+ status, headers, body = @app.call(env)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,52 @@
1
+ module CubaApi
2
+ module Rack
3
+ class Reloader
4
+
5
+ def self.parse( basedir, baseconstant )
6
+ Dir[ File.join( basedir, '**', '*.rb' ) ].each do |f|
7
+ last_modified = File.mtime( f ).to_f
8
+ if ! File.directory?( f ) && last_modified > @max_last_modified.to_f
9
+ @max_last_modified = last_modified
10
+ yield f
11
+ end
12
+ end
13
+ end
14
+
15
+ def self.maybe_remove_constant( f, basedir, baseconstant )
16
+ c = baseconstant
17
+ cname = nil
18
+ f.sub( /#{basedir}/, '' ).split( /\/|\./ ).each do |name|
19
+ if name != 'rb'
20
+ ( c = c.const_get( cname ) ) rescue nil
21
+ cname = name.split('_').each { |a| a.capitalize! }.join.to_sym
22
+ end
23
+ end
24
+ c.send( :remove_const, cname ) rescue nil
25
+ end
26
+
27
+ def self.doit( basedir, baseconstant )
28
+ if @max_last_modified
29
+ parse( basedir, baseconstant ) do |f|
30
+ maybe_remove_constant( f, basedir, baseconstant )
31
+ puts "[CubaAPI::Reloader] #{f}: #{load f}"
32
+ end
33
+ else
34
+ parse( basedir, baseconstant ) {}
35
+ end
36
+ end
37
+ end
38
+
39
+ class ReloaderRack
40
+ def initialize( app, basedir, baseconstant)
41
+ @app = app
42
+ @basedir = basedir
43
+ @baseconstant = baseconstant
44
+ end
45
+
46
+ def call(env)
47
+ Reloader.doit( @basedir, @baseconstant )
48
+ status, headers, body = @app.call(env)
49
+ end
50
+ end
51
+ end
52
+ end
@@ -17,8 +17,8 @@ module CubaApi
17
17
 
18
18
  # convenient method for status only responses
19
19
  def no_body( status )
20
- res.status = Rack::Utils.status_code( status )
21
- res.write Rack::Utils::HTTP_STATUS_CODES[ res.status ]
20
+ res.status = ::Rack::Utils.status_code( status )
21
+ res.write ::Rack::Utils::HTTP_STATUS_CODES[ res.status ]
22
22
  res['Content-Type' ] = 'text/plain'
23
23
  end
24
24
 
@@ -1,8 +1,9 @@
1
1
  require 'spec_helper'
2
2
  require 'cuba_api/config'
3
+ require 'cuba_api/loggers'
3
4
  require 'cuba_api/utils'
4
- require 'cuba_api/write_aspect'
5
- require 'cuba_api/accept_content'
5
+ require 'cuba_api/aspects'
6
+ require 'cuba_api/aspects/accept_content'
6
7
  require 'yaml'
7
8
 
8
9
  class B
@@ -16,9 +17,10 @@ describe CubaApi::AcceptContent do
16
17
  before do
17
18
  Cuba.reset!
18
19
  Cuba.plugin CubaApi::Config
20
+ Cuba.plugin CubaApi::Loggers
19
21
  Cuba.plugin CubaApi::Utils
20
22
  Cuba[ :aspects ] = []
21
- Cuba.plugin CubaApi::WriteAspect
23
+ Cuba.plugin CubaApi::Aspects
22
24
  Cuba.plugin CubaApi::AcceptContent
23
25
  Cuba.accept :yaml
24
26
  Cuba.define do
@@ -1,11 +1,12 @@
1
- require 'spec_helper'
2
- require 'cuba_api/allow_session_rack'
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path( File.join( File.dirname( __FILE__), 'spec_helper' ) )
3
+ require 'cuba_api/rack/allow_session_rack'
3
4
 
4
- describe CubaApi::AllowSessionRack do
5
+ describe CubaApi::Rack::AllowSessionRack do
5
6
 
6
7
  before do
7
8
  Cuba.reset!
8
- Cuba.use CubaApi::AllowSessionRack, 'session', 'system'
9
+ Cuba.use CubaApi::Rack::AllowSessionRack, 'session', 'system'
9
10
  Cuba.use Rack::Session::Cookie, :secret => 'secret'
10
11
  Cuba.define do
11
12
  on 'session' do
@@ -1,6 +1,7 @@
1
1
  require 'spec_helper'
2
2
  require 'cuba_api/config'
3
- require 'cuba_api/write_aspect'
3
+ require 'cuba_api/loggers'
4
+ require 'cuba_api/aspects'
4
5
 
5
6
  module Plugin
6
7
  def one( obj, opts )
@@ -14,13 +15,14 @@ module Plugin
14
15
  end
15
16
  end
16
17
 
17
- describe CubaApi::WriteAspect do
18
+ describe CubaApi::Aspects do
18
19
 
19
20
  before do
20
21
  Cuba.reset!
21
22
  Cuba.plugin CubaApi::Config
22
23
  Cuba[ :aspects ] = []
23
- Cuba.plugin CubaApi::WriteAspect
24
+ Cuba.plugin CubaApi::Loggers
25
+ Cuba.plugin CubaApi::Aspects
24
26
  Cuba.plugin Plugin
25
27
  Cuba.append_aspect :one
26
28
  Cuba.prepend_aspect :two
@@ -11,6 +11,10 @@ describe CubaApi::Cors do
11
11
  Cuba.plugin CubaApi::Cors
12
12
  Cuba.define do
13
13
 
14
+ on_cors 'no' do |who|
15
+ res.write "no"
16
+ end
17
+
14
18
  on_cors 'path/to/:who' do |who|
15
19
  on post do
16
20
  res.write "post from #{who}"
@@ -115,4 +119,14 @@ describe CubaApi::Cors do
115
119
  _, _, resp = Cuba.call( env )
116
120
  resp.join.must.eq 'frodo posted'
117
121
  end
122
+
123
+ it 'should pass through on no cors' do
124
+ env[ 'HTTP_ORIGIN' ] = nil
125
+ env[ 'PATH_INFO' ] = '/no/frodo'
126
+ env[ 'SCRIPT_NAME' ] = '/no/frodo'
127
+ env[ 'REQUEST_METHOD' ] = 'GET'
128
+
129
+ _, _, resp = Cuba.call( env )
130
+ resp.join.must.eq 'no'
131
+ end
118
132
  end
@@ -1,5 +1,6 @@
1
1
  require File.expand_path( File.join( File.dirname( __FILE__ ),
2
2
  'spec_helper.rb' ) )
3
+ require 'cuba_api/loggers'
3
4
  require 'cuba_api/config'
4
5
  require 'cuba_api/utils'
5
6
  require 'cuba_api/guard'
@@ -12,6 +13,7 @@ describe CubaApi::Guard do
12
13
  before do
13
14
  Cuba.reset!
14
15
  Cuba.plugin CubaApi::Config
16
+ Cuba.plugin CubaApi::Loggers
15
17
  Cuba.plugin CubaApi::Utils
16
18
  Cuba.plugin CubaApi::Guard
17
19
  Cuba.define do
@@ -51,7 +53,7 @@ describe CubaApi::Guard do
51
53
  res.write "post"
52
54
  end
53
55
  on_guard :get do
54
- res.write "get#{allowed_associations ? allowed_associations.inspect : nil}"
56
+ res.write "get#{allowed_associations.inspect.gsub( /nil/, '' )}"
55
57
  end
56
58
  on_guard :put do
57
59
  res.write "put"
@@ -83,10 +85,10 @@ describe CubaApi::Guard do
83
85
  env = { 'PATH_INFO' => '/users/accounts',
84
86
  'SCRIPT_NAME' => '/users/accounts' }
85
87
 
86
- user = guard.permission( 'users' ) do |u|
88
+ user = guard.permission_for( 'users' ) do |u|
87
89
  u.allow_all
88
90
  end
89
- guard.permission( 'admins' ) do |a|
91
+ guard.permission_for( 'admins' ) do |a|
90
92
  a.parent = user
91
93
  a.allow_all
92
94
  end
@@ -98,10 +100,10 @@ describe CubaApi::Guard do
98
100
  it 'allow all' do
99
101
  env = { 'PATH_INFO' => '/users/accounts',
100
102
  'SCRIPT_NAME' => '/users/accounts' }
101
- user = guard.permission( 'users' ) do |u|
103
+ user = guard.permission_for( 'users' ) do |u|
102
104
  u.allow_all
103
105
  end
104
- guard.permission( 'accounts' ) do |a|
106
+ guard.permission_for( 'accounts' ) do |a|
105
107
  a.parent = user
106
108
  a.allow_all
107
109
  end
@@ -129,8 +131,8 @@ describe CubaApi::Guard do
129
131
  end
130
132
 
131
133
  it 'denies all requests without associated id' do
132
- guard.permission( 'users' ) do |u|
133
- u.allow_all
134
+ guard.permission_for( 'users' ) do |u|
135
+ u.allow_all( 42 )
134
136
  end
135
137
 
136
138
  ['GET', 'POST','PUT', 'DELETE' ].each do |m|
@@ -141,7 +143,7 @@ describe CubaApi::Guard do
141
143
  end
142
144
 
143
145
  it 'denies all requests with wrong associated id' do
144
- guard.permission( 'users', 13 ) do |u|
146
+ guard.permission_for( 'users', 13 ) do |u|
145
147
  u.allow_all
146
148
  end
147
149
 
@@ -159,7 +161,7 @@ describe CubaApi::Guard do
159
161
  end
160
162
 
161
163
  it 'allows all requests with associated id' do
162
- guard.permission( 'users', 42 ) do |u|
164
+ guard.permission_for( 'users', 42 ) do |u|
163
165
  u.allow_all
164
166
  end
165
167
 
@@ -188,7 +190,7 @@ describe CubaApi::Guard do
188
190
  end
189
191
 
190
192
  it 'allows all request' do
191
- guard.permission( 'users' ) do |u|
193
+ guard.permission_for( 'users' ) do |u|
192
194
  u.allow_all
193
195
  end
194
196
 
@@ -200,7 +202,7 @@ describe CubaApi::Guard do
200
202
  end
201
203
 
202
204
  it 'allows retrieve' do
203
- guard.permission( 'users' ) do |u|
205
+ guard.permission_for( 'users' ) do |u|
204
206
  u.allow_retrieve
205
207
  end
206
208
 
@@ -217,7 +219,7 @@ describe CubaApi::Guard do
217
219
  end
218
220
 
219
221
  it 'allows retrieve and create' do
220
- guard.permission( 'users' ) do |u|
222
+ guard.permission_for( 'users' ) do |u|
221
223
  u.allow_retrieve
222
224
  u.allow_create
223
225
  end
@@ -234,7 +236,7 @@ describe CubaApi::Guard do
234
236
  end
235
237
 
236
238
  it 'allows retrieve and create and update' do
237
- guard.permission( 'users' ) do |u|
239
+ guard.permission_for( 'users' ) do |u|
238
240
  u.allow_mutate
239
241
  end
240
242
  ['GET', 'POST','PUT' ].each do |m|
@@ -248,7 +250,7 @@ describe CubaApi::Guard do
248
250
  end
249
251
 
250
252
  it 'allows retrieve and create and update and delete' do
251
- guard.permission( 'users' ) do |u|
253
+ guard.permission_for( 'users' ) do |u|
252
254
  u.allow_mutate
253
255
  u.allow_delete
254
256
  end
@@ -1,7 +1,8 @@
1
1
  require 'spec_helper'
2
- require 'cuba_api/write_aspect'
2
+ require 'cuba_api/aspects'
3
3
  require 'cuba_api/config'
4
- require 'cuba_api/response_status'
4
+ require 'cuba_api/loggers'
5
+ require 'cuba_api/aspects/response_status'
5
6
 
6
7
  class E
7
8
 
@@ -37,7 +38,9 @@ describe CubaApi::ResponseStatus do
37
38
  before do
38
39
  Cuba.reset!
39
40
  Cuba.plugin CubaApi::Config
40
- Cuba.plugin CubaApi::WriteAspect
41
+ Cuba.plugin CubaApi::Loggers
42
+ Cuba.plugin CubaApi::Aspects
43
+ Cuba.aspects.clear
41
44
  Cuba.plugin CubaApi::ResponseStatus
42
45
  Cuba.define do
43
46
  on get do
@@ -1,7 +1,8 @@
1
1
  require 'spec_helper'
2
2
  require 'cuba_api/config'
3
- require 'cuba_api/write_aspect'
4
- require 'cuba_api/serializer'
3
+ require 'cuba_api/loggers'
4
+ require 'cuba_api/aspects'
5
+ require 'cuba_api/aspects/serializer'
5
6
  require 'yaml'
6
7
  require 'ixtlan/babel/serializer'
7
8
 
@@ -24,7 +25,8 @@ describe CubaApi::Serializer do
24
25
  Cuba.reset!
25
26
  Cuba.plugin CubaApi::Config
26
27
  Cuba[ :aspects ] = []
27
- Cuba.plugin CubaApi::WriteAspect
28
+ Cuba.plugin CubaApi::Loggers
29
+ Cuba.plugin CubaApi::Aspects
28
30
  Cuba.plugin CubaApi::Serializer
29
31
  Cuba.plugin ToYaml
30
32
  Cuba.append_aspect :to_yaml
@@ -1,6 +1,8 @@
1
1
  # single spec setup
2
2
  $LOAD_PATH.unshift File.join( File.dirname( File.expand_path( File.dirname( __FILE__ ) ) ),
3
3
  'lib' )
4
+
5
+ gem 'minitest'
4
6
  require 'minitest/autorun'
5
7
 
6
8
  require 'cuba'
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cuba-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.1
5
- prerelease:
4
+ version: 0.6.2
6
5
  platform: ruby
7
6
  authors:
8
7
  - Christian Meier
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-10-22 00:00:00.000000000 Z
11
+ date: 2013-12-13 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: cuba
@@ -18,13 +17,11 @@ dependencies:
18
17
  - - ~>
19
18
  - !ruby/object:Gem::Version
20
19
  version: '3.1'
21
- none: false
22
20
  requirement: !ruby/object:Gem::Requirement
23
21
  requirements:
24
22
  - - ~>
25
23
  - !ruby/object:Gem::Version
26
24
  version: '3.1'
27
- none: false
28
25
  prerelease: false
29
26
  type: :runtime
30
27
  - !ruby/object:Gem::Dependency
@@ -34,13 +31,11 @@ dependencies:
34
31
  - - ~>
35
32
  - !ruby/object:Gem::Version
36
33
  version: '0.4'
37
- none: false
38
34
  requirement: !ruby/object:Gem::Requirement
39
35
  requirements:
40
36
  - - ~>
41
37
  - !ruby/object:Gem::Version
42
38
  version: '0.4'
43
- none: false
44
39
  prerelease: false
45
40
  type: :runtime
46
41
  - !ruby/object:Gem::Dependency
@@ -50,13 +45,11 @@ dependencies:
50
45
  - - ~>
51
46
  - !ruby/object:Gem::Version
52
47
  version: '0.8'
53
- none: false
54
48
  requirement: !ruby/object:Gem::Requirement
55
49
  requirements:
56
50
  - - ~>
57
51
  - !ruby/object:Gem::Version
58
52
  version: '0.8'
59
- none: false
60
53
  prerelease: false
61
54
  type: :runtime
62
55
  - !ruby/object:Gem::Dependency
@@ -66,13 +59,11 @@ dependencies:
66
59
  - - ~>
67
60
  - !ruby/object:Gem::Version
68
61
  version: '1.6'
69
- none: false
70
62
  requirement: !ruby/object:Gem::Requirement
71
63
  requirements:
72
64
  - - ~>
73
65
  - !ruby/object:Gem::Version
74
66
  version: '1.6'
75
- none: false
76
67
  prerelease: false
77
68
  type: :runtime
78
69
  - !ruby/object:Gem::Dependency
@@ -82,13 +73,11 @@ dependencies:
82
73
  - - ~>
83
74
  - !ruby/object:Gem::Version
84
75
  version: '1.6'
85
- none: false
86
76
  requirement: !ruby/object:Gem::Requirement
87
77
  requirements:
88
78
  - - ~>
89
79
  - !ruby/object:Gem::Version
90
80
  version: '1.6'
91
- none: false
92
81
  prerelease: false
93
82
  type: :development
94
83
  - !ruby/object:Gem::Dependency
@@ -98,13 +87,11 @@ dependencies:
98
87
  - - ~>
99
88
  - !ruby/object:Gem::Version
100
89
  version: '10.1'
101
- none: false
102
90
  requirement: !ruby/object:Gem::Requirement
103
91
  requirements:
104
92
  - - ~>
105
93
  - !ruby/object:Gem::Version
106
94
  version: '10.1'
107
- none: false
108
95
  prerelease: false
109
96
  type: :development
110
97
  - !ruby/object:Gem::Dependency
@@ -114,13 +101,11 @@ dependencies:
114
101
  - - ~>
115
102
  - !ruby/object:Gem::Version
116
103
  version: '5.0'
117
- none: false
118
104
  requirement: !ruby/object:Gem::Requirement
119
105
  requirements:
120
106
  - - ~>
121
107
  - !ruby/object:Gem::Version
122
108
  version: '5.0'
123
- none: false
124
109
  prerelease: false
125
110
  type: :development
126
111
  - !ruby/object:Gem::Dependency
@@ -130,13 +115,11 @@ dependencies:
130
115
  - - ~>
131
116
  - !ruby/object:Gem::Version
132
117
  version: '0.1'
133
- none: false
134
118
  requirement: !ruby/object:Gem::Requirement
135
119
  requirements:
136
120
  - - ~>
137
121
  - !ruby/object:Gem::Version
138
122
  version: '0.1'
139
- none: false
140
123
  prerelease: false
141
124
  type: :development
142
125
  - !ruby/object:Gem::Dependency
@@ -146,13 +129,11 @@ dependencies:
146
129
  - - ~>
147
130
  - !ruby/object:Gem::Version
148
131
  version: '0.2'
149
- none: false
150
132
  requirement: !ruby/object:Gem::Requirement
151
133
  requirements:
152
134
  - - ~>
153
135
  - !ruby/object:Gem::Version
154
136
  version: '0.2'
155
- none: false
156
137
  prerelease: false
157
138
  type: :development
158
139
  description: add content negogiation, serialization of objects (their attributes map), and some helpers for authentication + authorization to the cuba framework
@@ -168,33 +149,42 @@ files:
168
149
  - lib/cuba_api.rb~
169
150
  - lib/cuba_api/write_aspect.rb~
170
151
  - lib/cuba_api/config.rb~
171
- - lib/cuba_api/reloader_rack.rb
172
152
  - lib/cuba_api/utils.rb
173
- - lib/cuba_api/allow_session_rack.rb
153
+ - lib/cuba_api/aspects.rb~
174
154
  - lib/cuba_api/cors.rb~
175
155
  - lib/cuba_api/input_filter.rb~
176
156
  - lib/cuba_api/response_status.rb~
157
+ - lib/cuba_api/aspects.rb
177
158
  - lib/cuba_api/reponse_status.rb~
178
- - lib/cuba_api/write_aspect.rb
179
159
  - lib/cuba_api/write_aspects.rb~
180
160
  - lib/cuba_api/serializer.rb~
181
161
  - lib/cuba_api/ext2mime_rack.rb~
182
- - lib/cuba_api/response_status.rb
183
162
  - lib/cuba_api/cors.rb
163
+ - lib/cuba_api/logger.rb~
184
164
  - lib/cuba_api/utils.rb~
185
165
  - lib/cuba_api/guard.rb
186
166
  - lib/cuba_api/current_user.rb~
187
167
  - lib/cuba_api/allow_session_rack.rb~
188
168
  - lib/cuba_api/config.rb
189
- - lib/cuba_api/accept_content.rb
190
- - lib/cuba_api/ext2mime_rack.rb
191
169
  - lib/cuba_api/input_filter.rb
170
+ - lib/cuba_api/loggers.rb~
192
171
  - lib/cuba_api/accept_content.rb~
193
172
  - lib/cuba_api/reloader_rack.rb~
194
173
  - lib/cuba_api/no_session_rack.rb~
195
- - lib/cuba_api/serializer.rb
174
+ - lib/cuba_api/loggers.rb
196
175
  - lib/cuba_api/guard.rb~
197
176
  - lib/cuba_api/current_user.rb
177
+ - lib/cuba_api/rack/reloader_rack.rb
178
+ - lib/cuba_api/rack/allow_session_rack.rb
179
+ - lib/cuba_api/rack/ext2mime_rack.rb~
180
+ - lib/cuba_api/rack/allow_session_rack.rb~
181
+ - lib/cuba_api/rack/ext2mime_rack.rb
182
+ - lib/cuba_api/rack/reloader_rack.rb~
183
+ - lib/cuba_api/aspects/response_status.rb~
184
+ - lib/cuba_api/aspects/response_status.rb
185
+ - lib/cuba_api/aspects/accept_content.rb
186
+ - lib/cuba_api/aspects/accept_content.rb~
187
+ - lib/cuba_api/aspects/serializer.rb
198
188
  - spec/serializer_spec.rb
199
189
  - spec/cors_with_config_spec.rb~
200
190
  - spec/accept_spec.rb
@@ -223,6 +213,7 @@ files:
223
213
  homepage: http://github.com/mkristian/cuba-api
224
214
  licenses:
225
215
  - MIT
216
+ metadata: {}
226
217
  post_install_message:
227
218
  rdoc_options: []
228
219
  require_paths:
@@ -232,18 +223,16 @@ required_ruby_version: !ruby/object:Gem::Requirement
232
223
  - - '>='
233
224
  - !ruby/object:Gem::Version
234
225
  version: '0'
235
- none: false
236
226
  required_rubygems_version: !ruby/object:Gem::Requirement
237
227
  requirements:
238
228
  - - '>='
239
229
  - !ruby/object:Gem::Version
240
230
  version: '0'
241
- none: false
242
231
  requirements: []
243
232
  rubyforge_project:
244
- rubygems_version: 1.8.24
233
+ rubygems_version: 2.1.9
245
234
  signing_key:
246
- specification_version: 3
235
+ specification_version: 4
247
236
  summary: set of plugins for using cuba as API server
248
237
  test_files:
249
238
  - spec/serializer_spec.rb
@@ -1,30 +0,0 @@
1
- module CubaApi
2
- module ResponseStatus
3
- def response_status( obj, options = {})
4
- if options[:response_status] != false
5
- if obj.respond_to?( :errors ) && obj.errors.size > 0
6
- res.status = 412 # Precondition Failed
7
- obj = obj.errors
8
- if obj.respond_to? :to_hash
9
- warn "[CubaApi::ResponseStatus] #{obj.to_hash.values.join( "\n" )}"
10
- else
11
- warn "[CubaApi::ResponseStatus] #{obj.inspect}"
12
- end
13
- elsif req.post?
14
- res.status = 201 # Created
15
- if obj.respond_to?( :id ) && ! res[ 'Location' ]
16
- res[ 'Location' ] = env[ 'SCRIPT_NAME' ].to_s + "/#{obj.id}"
17
- end
18
- elsif req.delete?
19
- res.status = 204 # No Content
20
- obj = ''
21
- end
22
- end
23
- obj
24
- end
25
-
26
- def self.included( base )
27
- base.prepend_aspect :response_status
28
- end
29
- end
30
- end