tzispa 0.5.10 → 0.5.11

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 73281443ab56c5d37e05bccc7896d3af2acb3415
4
- data.tar.gz: '03076458d15ac0598119430311808949ad0c57e7'
3
+ metadata.gz: 9e70cadefd940ba6c29f9e922288ae5d6e26f806
4
+ data.tar.gz: 9d0803b6898b4f23d8117ee20c5854e13bca99ab
5
5
  SHA512:
6
- metadata.gz: 1ce98d4842005c2af213bd7a560c7b70cc4e8213f9ebc08a7c8909e77cc74817f936bff2eeccf637bce136c6afcde18f8640317788175f9042a0f57c7b94144e
7
- data.tar.gz: '079524201c5c1d25dc23ba1de6258eba590a4cd773a968674e07e98224cf2156dac28d3f52a69d756c17565e41910c7a97afe86694a8e68f9d5730e0558e8323'
6
+ metadata.gz: 83d6b14372cd570718a36f4a68f7480591923033c91046ece2d3c27742c9686872b69457e9534127385ba3ee0f23690cdcc614578be2dedf63c68bc1c851da17
7
+ data.tar.gz: e7ae49e10763e8bdcf4655a15c3ca68dad2651fba71b0e9d96245820a69b75b2cdcb92c9608202d8aea7dd17ea1ae562637f33889e20d1ba3e27a45260dffcee
data/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@ Tzispa
2
2
 
3
3
  General purpose web framework
4
4
 
5
+ ## v0.5.11
6
+ - moved app config files location
7
+ - moved app locales base dir
8
+ - api sign checking has been moved to handlers by helpers dsl
9
+ - api dispatch code improvement and fixes
10
+ - code reorganization to expose better interfaces
11
+
5
12
  ## v0.5.10
6
13
  - fix: check if the given layout is the default_layout in config before promote into the path params hash
7
14
  - add tmp folder in the project creation cli command
@@ -18,7 +25,7 @@ General purpose web framework
18
25
  - add path building methods for rig layouts in lib/tzispa/http/context.rb
19
26
 
20
27
  ## v0.5.7
21
- - add provides DSL method to specify allowe verbs in api handlers
28
+ - add provides DSL method to specify allowed verbs in api handlers
22
29
  - handler calling improvements in api the controller
23
30
 
24
31
  ## v0.5.6
@@ -2,6 +2,8 @@
2
2
 
3
3
  require 'forwardable'
4
4
  require 'json'
5
+ require 'tzispa/helpers/provider'
6
+ require 'tzispa/helpers/sign_requirer'
5
7
 
6
8
  module Tzispa
7
9
  module Api
@@ -12,13 +14,15 @@ module Tzispa
12
14
  super("Unknown verb: '#{s}' called in api handler '#{name}'")
13
15
  end
14
16
  end
17
+ class InvalidSign < ApiException; end
15
18
 
16
19
  class Handler
20
+ include Tzispa::Helpers::Provider
21
+ include Tzispa::Helpers::SignRequirer
17
22
  extend Forwardable
18
23
 
19
- def_delegators :@context, :request, :response, :app
20
-
21
- attr_reader :context, :status, :response_verb, :data
24
+ attr_reader :context, :response_verb, :data, :status
25
+ def_delegators :@context, :request, :response, :app, :repository, :config
22
26
 
23
27
  HANDLED_UNDEFINED = nil
24
28
  HANDLED_OK = 1
@@ -36,54 +40,53 @@ module Tzispa
36
40
  @context = context
37
41
  end
38
42
 
39
- def result(response_verb:, status: HANDLED_UNDEFINED, data: nil, detailed_error: nil)
40
- @status = status
43
+ def result(response_verb:, data: nil, status: nil, error: nil)
44
+ @status = status if status
41
45
  @response_verb = response_verb
42
46
  @data = data
43
- @detailed_error = detailed_error
47
+ @error = error
48
+ end
49
+
50
+ def result_json(data, status: nil)
51
+ result response_verb: :json, data: data.to_json, status: status
44
52
  end
45
53
 
46
- def result_json(status=HANDLED_UNDEFINED, data=nil, detailed_error=nil)
47
- result response_verb: :json, status: status, data: data.to_json, detailed_error: detailed_error
54
+ def result_download(data, status: nil)
55
+ result response_verb: :download, data: data, status: status
56
+ end
57
+
58
+ def not_found
59
+ result response_verb: :not_found
48
60
  end
49
61
 
50
62
  def message
51
- if @status.nil?
52
- nil
53
- elsif @status >= HANDLED_OK && @status <= HANDLED_ERROR
54
- HANDLED_MESSAGES[@status]
55
- elsif @status > HANDLED_ERROR && @status < HANDLED_RESULT
56
- error_message @status
57
- elsif @status > HANDLED_RESULT
58
- result_messages @status
59
- else
60
- nil
63
+ case ss = status.to_i
64
+ when ss >= HANDLED_OK && ss <= HANDLED_ERROR
65
+ HANDLED_MESSAGES[status]
66
+ when ss > HANDLED_ERROR && ss < HANDLED_RESULT
67
+ error_message status
68
+ when ss > HANDLED_RESULT
69
+ result_messages status
61
70
  end
62
71
  end
63
72
 
64
73
  def call(verb, predicate=nil)
65
- raise UnknownHandlerVerb.new(verb, self.class.name) unless self.class.provides? verb
66
- # allow compound predicates
74
+ raise UnknownHandlerVerb.new(verb, self.class.name) unless provides? verb
75
+ raise InvalidSign.new if sign_required? && !sign_valid?
76
+ # process compound predicates
67
77
  args = predicate ? predicate.split(',') : nil
68
78
  send verb, *args
69
79
  end
70
80
 
71
- def self.provides(*args)
72
- (@provides ||= Hash.new).tap { |prv|
73
- args&.each { |s|
74
- prv[s.to_sym] = s
75
- }
76
- }
81
+ def set_status(value)
82
+ @status = value
77
83
  end
78
84
 
79
- def self.provides?(verb)
80
- value = verb.to_sym
81
- @provides&.include?(value) && public_method_defined?(@provides[value])
82
- end
83
85
 
84
- def self.mapping(source, dest)
85
- @provides ||= Hash.new
86
- @provides[source] = dest
86
+ protected
87
+
88
+ def static_path_sign?
89
+ context.path_sign? context.router_params[:sign], context.router_params[:handler], context.router_params[:verb], context.router_params[:predicate]
87
90
  end
88
91
 
89
92
  private
@@ -93,7 +96,7 @@ module Tzispa
93
96
  end
94
97
 
95
98
  def error_message(status)
96
- "#{self.class::ERROR_MESSAGES[status]}#{': '+@detailed_error if @detailed_error}" if (defined?( self.class::ERROR_MESSAGES ) && self.class::ERROR_MESSAGES.is_a?(Hash))
99
+ "#{self.class::ERROR_MESSAGES[status]}#{': '+@error.to_s if @error}" if (defined?( self.class::ERROR_MESSAGES ) && self.class::ERROR_MESSAGES.is_a?(Hash))
97
100
  end
98
101
 
99
102
 
data/lib/tzispa/app.rb CHANGED
@@ -77,16 +77,14 @@ module Tzispa
77
77
  end
78
78
 
79
79
  def load!
80
- Mutex.new.synchronize {
80
+ self.class.synchronize {
81
81
  load_locales
82
- @repository = Data::Repository.new(@config.repository.to_h).load! if @config.respond_to? :repository
83
- @engine = Rig::Engine.new(self, @config.template_cache.enabled, @config.template_cache.size)
84
- @logger = Logger.new("logs/#{@domain.name}.log", 'weekly')
85
- @logger.level = @config.respond_to?(:developing) && @config.developing ? Logger::DEBUG : Logger::INFO
86
- @domain.require_dir 'helpers'
87
- @domain.require_dir 'services'
88
- @domain.require_dir 'api'
89
- @domain.require_dir 'middleware'
82
+ @repository = Data::Repository.new(config.repository.to_h).load! if config.respond_to? :repository
83
+ @engine = Rig::Engine.new(self, config.template_cache.enabled, config.template_cache.size)
84
+ @logger = Logger.new("logs/#{domain.name}.log", config.logging.shift_age).tap { |log|
85
+ log.level = config.developing ? Logger::DEBUG : Logger::INFO
86
+ } if config.logging&.enabled
87
+ domain_requires
90
88
  @loaded = true
91
89
  }
92
90
  self
@@ -98,10 +96,17 @@ module Tzispa
98
96
 
99
97
  private
100
98
 
99
+ def domain_requires
100
+ domain.require_dir 'helpers'
101
+ domain.require_dir 'services'
102
+ domain.require_dir 'api'
103
+ domain.require_dir 'middleware'
104
+ end
105
+
101
106
  def load_locales
102
107
  if @config.respond_to?(:locales)
103
108
  I18n.load_path = Dir["config/locales/*.yml"]
104
- I18n.load_path += Dir["#{@domain.path}/config/locales/*.yml"]
109
+ I18n.load_path += Dir["#{@domain.path}/locales/*.yml"]
105
110
  end
106
111
  end
107
112
 
@@ -13,14 +13,13 @@ module Tzispa
13
13
 
14
14
  attr_reader :domain, :cfname
15
15
 
16
- def initialize(domain, configname=nil)
16
+ def initialize(domain)
17
17
  @domain = domain
18
- @cfname = configname || CONFIG_FILENAME
19
18
  @cftime = nil
20
19
  end
21
20
 
22
21
  def filename
23
- @filename ||= "#{domain.path}/config/#{cfname}.yml".freeze
22
+ @filename ||= "config/#{domain.name}.yml"
24
23
  end
25
24
 
26
25
  def load!
@@ -45,6 +44,7 @@ module Tzispa
45
44
  cfg['default_encoding'] = 'utf-8'
46
45
  cfg['auth_required'] = false
47
46
  cfg['salt'] = secret(24)
47
+ cfg['secret'] = secret(36)
48
48
  cfg['locales'] = Hash.new.tap { |loc|
49
49
  loc['preload'] = true
50
50
  loc['default'] = locale
@@ -17,13 +17,10 @@ module Tzispa
17
17
 
18
18
  include Tzispa::Helpers::Response
19
19
 
20
- attr_reader :handler
21
20
 
22
21
  def self.generate_handler(domain, name)
23
- @domain = domain
24
- @handler_name = name
25
22
  raise "The handler '#{name}' already exist" if File.exist?(handler_class_file)
26
- File.open(handler_class_file, "w") { |f|
23
+ File.open(handler_class_file(domain, name), "w") { |f|
27
24
  handler_code = TzString.new
28
25
  f.puts handler_code.indenter("require 'tzispa/api/handler'\n\n")
29
26
  level = 0
@@ -39,81 +36,76 @@ module Tzispa
39
36
  }
40
37
  end
41
38
 
42
-
43
39
  def dispatch!
44
- @handler_name, domain_name = context.router_params[:handler].split('.').reverse
45
- @domain = domain_name.nil? ? context.app.domain : Tzispa::Domain.new(name: domain_name)
46
- @verb = context.router_params[:verb]
47
- @predicate = context.router_params[:predicate]
48
- @handler = handler_class.new(context)
49
- handler.call @verb, @predicate
50
- context.flash << handler.message
51
- send handler.response_verb if handler.response_verb
40
+ handler_name, domain_name = context.router_params[:handler].split('.').reverse
41
+ domain = domain_name.nil? ? context.app.domain : Tzispa::Domain.new(name: domain_name)
42
+ verb = context.router_params[:verb]
43
+ predicate = context.router_params[:predicate]
44
+ handler = self.class.handler_class(domain, handler_name).new(context)
45
+ handler.call verb, predicate
46
+ send(handler.response_verb, handler) if handler.response_verb
52
47
  response.finish
53
48
  end
54
49
 
55
- def redirect
56
- url = if handler.data && !handler.data.strip.empty?
57
- handler.data.start_with?('#') ? "#{request.referer}#{handler.data}" : handler.data
50
+ def redirect(target)
51
+ url = if target.data && !target.data.strip.empty?
52
+ target.data.start_with?('#') ? "#{request.referer}#{target.data}" : target.data
58
53
  else
59
54
  request.referer
60
55
  end
56
+ context.flash << target.message if config.sessions&.enabled
61
57
  context.redirect url, config.absolute_redirects, response
62
58
  end
63
59
 
64
- def html
65
- response.body << handler.data
60
+ def html(content)
66
61
  content_type :htm
67
- set_action_headers
62
+ response.body << content.data
63
+ set_api_headers content.status
68
64
  end
69
65
 
70
- def json
71
- if handler.data.is_a?(::Hash)
72
- data = handler.data
73
- data[:__result_status] = handler.status
74
- data[:__result_message] = handler.message
75
- else
76
- data = JSON.parse(handler.data)
77
- end
78
- response.body << data.to_json
66
+ def json(content)
79
67
  content_type :json
80
- set_action_headers
68
+ data = ::Hash === content.data || ::Array === content.data ? content.data : JSON.parse(content.data)
69
+ response.body << data.to_json
70
+ set_api_headers content.status
81
71
  end
82
72
 
83
- def text
84
- response.body << handler.data
73
+ def text(content)
85
74
  content_type :text
86
- set_action_headers
75
+ response.body << content.data
76
+ set_api_headers content.status
87
77
  end
88
78
 
89
- def download
90
- send_file handler.data[:path], handler.data
79
+ def download(content)
80
+ send_file content.data[:path], content.data
91
81
  end
92
82
 
93
- def handler_class_name
94
- "#{TzString.camelize @handler_name}Handler"
95
- end
83
+ class << self
96
84
 
97
- def handler_class_file
98
- "#{@domain.path}/api/#{@handler_name}.rb"
99
- end
85
+ def handler_class_name(handler_name)
86
+ "#{TzString.camelize handler_name}Handler"
87
+ end
100
88
 
101
- def handler_namespace
102
- "#{TzString.camelize @domain.name }::Api"
103
- end
89
+ def handler_class_file(domain, handler_name)
90
+ "#{domain.path}/api/#{handler_name}.rb"
91
+ end
104
92
 
105
- def handler_class
106
- @domain.require "api/#{@handler_name}"
107
- TzString.constantize "#{handler_namespace}::#{handler_class_name}"
108
- end
93
+ def handler_namespace(domain)
94
+ "#{TzString.camelize domain.name }::Api"
95
+ end
109
96
 
97
+ def handler_class(domain, handler_name)
98
+ domain.require "api/#{handler_name}"
99
+ TzString.constantize "#{handler_namespace domain}::#{handler_class_name handler_name}"
100
+ end
110
101
 
111
- private
102
+ end
112
103
 
104
+ private
113
105
 
114
- def set_action_headers
115
- response['X-API'] = "#{context.router_params[:sign]}:#{context.router_params[:handler]}:#{context.router_params[:verb]}:#{context.router_params[:predicate]}"
116
- response['X-API-STATE'] = "#{handler.status}"
106
+ def set_api_headers(status)
107
+ response['X-API'] = "#{context.router_params[:handler]}:#{context.router_params[:verb]}:#{context.router_params[:predicate]}"
108
+ response['X-API-STATE'] = "#{status.to_i}"
117
109
  end
118
110
 
119
111
  end
@@ -5,25 +5,8 @@ require 'tzispa/helpers/security'
5
5
  module Tzispa
6
6
  module Controller
7
7
  class SignedApi < Api
8
-
9
- include Tzispa::Helpers::Security
10
-
11
-
12
- def dispatch!
13
- raise Error::InvalidSign.new unless sign?
14
- super
15
- end
16
-
17
- private
18
-
19
- def sign?
20
- context.router_params[:sign] == sign_array([
21
- context.router_params[:handler],
22
- context.router_params[:verb],
23
- context.router_params[:predicate]
24
- ],
25
- context.app.config.salt)
26
- end
8
+
9
+ # deprecated !!
27
10
 
28
11
  end
29
12
  end
@@ -125,6 +125,11 @@ module Tzispa
125
125
  end
126
126
  end
127
127
 
128
+ def path_sign?(sign, *args)
129
+ sign == sign_array(args, config.salt)
130
+ end
131
+
132
+
128
133
  end
129
134
 
130
135
  end
data/lib/tzispa/routes.rb CHANGED
@@ -55,7 +55,7 @@ module Tzispa
55
55
  end
56
56
 
57
57
  def route_rig_signed_api(path, controller: nil, methods: nil)
58
- routing :sapi, path, controller || 'signed_api:dispatch!', methods: methods
58
+ routing :sapi, path, controller || 'api:dispatch!', methods: methods
59
59
  end
60
60
 
61
61
  def route_rig_layout(layout, path, controller: nil, methods: nil)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tzispa
4
- VERSION = '0.5.10'
4
+ VERSION = '0.5.11'
5
5
  FRAMEWORK_NAME = 'Tzispa'
6
6
  GEM_NAME = 'tzispa'
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tzispa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.10
4
+ version: 0.5.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Juan Antonio Piñero
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-10-27 00:00:00.000000000 Z
11
+ date: 2016-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -174,7 +174,6 @@ files:
174
174
  - lib/tzispa/controller/http_error.rb
175
175
  - lib/tzispa/controller/layout.rb
176
176
  - lib/tzispa/controller/signed_api.rb
177
- - lib/tzispa/data/entity.rb
178
177
  - lib/tzispa/domain.rb
179
178
  - lib/tzispa/http/context.rb
180
179
  - lib/tzispa/http/request.rb
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'tzispa/utils/string'
4
-
5
- module Tzispa
6
- module Data
7
- module Entity
8
-
9
- def self.included(base)
10
- base.extend(ClassMethods)
11
- end
12
-
13
- def entity!
14
- @__entity || @__entity = self.class.entity_class.new(self)
15
- end
16
-
17
- module ClassMethods
18
- def entity_class
19
- class_variable_defined?(:@@__entity_class) ?
20
- class_variable_get(:@@__entity_class) :
21
- class_variable_set(:@@__entity_class, TzString.constantize("#{self}Entity") )
22
- end
23
- end
24
-
25
- #unless model_class.respond_to?(:entity_class!)
26
- # model_class.send(:define_singleton_method, :entity_class) {
27
- # class_variable_defined?(:@@__entity_class) ?
28
- # class_variable_get(:@@__entity_class) :
29
- # class_variable_set(:@@__entity_class, TzString.constantize("#{self}Entity") )
30
- # }
31
- #end
32
- #model_class.send(:define_method, :entity!) {
33
- # instance_variable_defined?(:@__entity) ?
34
- # instance_variable_get(:@__entity) :
35
- # instance_variable_set(:@__entity, self.class.entity_class!.new(self))
36
- #}
37
-
38
- end
39
- end
40
- end