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 +4 -4
- data/CHANGELOG.md +8 -1
- data/lib/tzispa/api/handler.rb +37 -34
- data/lib/tzispa/app.rb +15 -10
- data/lib/tzispa/config/appconfig.rb +3 -3
- data/lib/tzispa/controller/api.rb +43 -51
- data/lib/tzispa/controller/signed_api.rb +2 -19
- data/lib/tzispa/http/context.rb +5 -0
- data/lib/tzispa/routes.rb +1 -1
- data/lib/tzispa/version.rb +1 -1
- metadata +2 -3
- data/lib/tzispa/data/entity.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9e70cadefd940ba6c29f9e922288ae5d6e26f806
|
4
|
+
data.tar.gz: 9d0803b6898b4f23d8117ee20c5854e13bca99ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
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
|
data/lib/tzispa/api/handler.rb
CHANGED
@@ -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
|
-
|
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:,
|
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
|
-
@
|
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
|
47
|
-
result response_verb: :
|
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
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
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
|
66
|
-
|
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
|
72
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
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]}#{': '+@
|
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
|
-
|
80
|
+
self.class.synchronize {
|
81
81
|
load_locales
|
82
|
-
@repository = Data::Repository.new(
|
83
|
-
@engine = Rig::Engine.new(self,
|
84
|
-
@logger = Logger.new("logs/#{
|
85
|
-
|
86
|
-
|
87
|
-
|
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}/
|
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
|
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 ||= "
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
handler.call
|
50
|
-
|
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
|
57
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
75
|
+
response.body << content.data
|
76
|
+
set_api_headers content.status
|
87
77
|
end
|
88
78
|
|
89
|
-
def download
|
90
|
-
send_file
|
79
|
+
def download(content)
|
80
|
+
send_file content.data[:path], content.data
|
91
81
|
end
|
92
82
|
|
93
|
-
|
94
|
-
"#{TzString.camelize @handler_name}Handler"
|
95
|
-
end
|
83
|
+
class << self
|
96
84
|
|
97
|
-
|
98
|
-
|
99
|
-
|
85
|
+
def handler_class_name(handler_name)
|
86
|
+
"#{TzString.camelize handler_name}Handler"
|
87
|
+
end
|
100
88
|
|
101
|
-
|
102
|
-
|
103
|
-
|
89
|
+
def handler_class_file(domain, handler_name)
|
90
|
+
"#{domain.path}/api/#{handler_name}.rb"
|
91
|
+
end
|
104
92
|
|
105
|
-
|
106
|
-
|
107
|
-
|
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
|
-
|
102
|
+
end
|
112
103
|
|
104
|
+
private
|
113
105
|
|
114
|
-
def
|
115
|
-
response['X-API'] = "#{context.router_params[:
|
116
|
-
response['X-API-STATE'] = "#{
|
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
|
-
|
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
|
data/lib/tzispa/http/context.rb
CHANGED
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 || '
|
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)
|
data/lib/tzispa/version.rb
CHANGED
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.
|
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-
|
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
|
data/lib/tzispa/data/entity.rb
DELETED
@@ -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
|