sbsm 1.5.5 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2eda12c46b1116c92dfe97027a53565f71715cd3
4
- data.tar.gz: 709c375fec68690bbabffebe91886f34f1b61503
2
+ SHA256:
3
+ metadata.gz: b93d9bf6799d6d4acbc8d4b7da58620c38d3f25778ebc6b56362b8c122d563de
4
+ data.tar.gz: 9a31b8e5479f81901bbe32ddc555984343750be0cbab2fab46ec26f0713bbc89
5
5
  SHA512:
6
- metadata.gz: 5086f2d5dc29a833ecc655695deac70c6373aa0363a5fc82ae9b7e9fe1dbaa9a121f700d36d5bb152a217cf6a949c6844114fb18cb7fe2fe0a3afc2f4221cf6d
7
- data.tar.gz: 3be17e83ef6c00f6a1b192000848fdeae6d95ce294aa13ab28df53ba223208fcf073484b696ea5dca320d8697408b3ac14b1868db8bd0ea916206b8919c69771
6
+ metadata.gz: 8787656db28102c2e04512f319007348d5fa2ee39988f2a111718a6c94650b2d1637d5914a87f69ef558a5e167dee190e71985df8c27b97dd16a1708201751a4
7
+ data.tar.gz: f6d74035ec0fd830acbd2c599a20434fc674963093d955a220df0a7cbe942dd82dc091f7d71b2e3c62bc283821e3437e8c7d08009513f723baca9a7844230a41
@@ -7,21 +7,15 @@ notifications:
7
7
 
8
8
  cache: bundler
9
9
 
10
- sudo: false
11
-
12
10
  before_install:
13
11
  - gem --version
14
-
15
- bundler_args: --without debugger
12
+ - bundle config set without 'debugger'
16
13
 
17
14
  rvm:
15
+ - 2.7.1
16
+ - 2.5.0
18
17
  - ruby-head
19
- - 2.2.3
20
- - 2.4.0
21
- - 2.3.0
22
18
  matrix:
23
19
  allow_failures:
24
- # On november 1 had failure compiling the child_processes
25
20
  - rvm: ruby-head
26
- - rvm: 2.2.3 # Test for LogLevel does not work
27
- - rvm: 2.3.0 # Test for LogLevel does not work
21
+ - rvm: 2.5.0 # Test for LogLevel does not work
@@ -1,3 +1,25 @@
1
+ === 1.6.0 / 13.06.2020
2
+
3
+ * Remove calls to obsolete taint/untaint methods
4
+
5
+ === 1.5.9 / 30.08.2017
6
+
7
+ * Fix recognition whether we are using HTTPS or not
8
+ * Fix using http_headers in views
9
+ * Allow non standard HTTP-Port
10
+
11
+ === 1.5.8 / 8.08.2017
12
+
13
+ * Fix recognizing mime type for unusual extensions
14
+
15
+ === 1.5.7 / 8.08.2017
16
+
17
+ * Return nice 404 error for non existing files
18
+
19
+ === 1.5.6 / 12.07.2017
20
+
21
+ * Handle several IPs in X_FORWARDED_FOR
22
+
1
23
  === 1.5.5 / 12.07.2017
2
24
 
3
25
  * Do not return body if HEAD is requested
File without changes
@@ -106,10 +106,9 @@ module SBSM
106
106
  else
107
107
  file_name = File.expand_path(File.join('doc', request.path))
108
108
  end
109
-
110
109
  if File.file?(file_name)
111
- if File.extname(file_name).length > 0
112
- mime_type = MimeMagic.by_extension(File.extname(file_name)).type
110
+ if File.extname(file_name).length > 0 && (mime_info = MimeMagic.by_extension(File.extname(file_name)))
111
+ mime_type = mime_info.type
113
112
  else
114
113
  mime_type = MimeMagic.by_path(file_name)
115
114
  end
@@ -117,7 +116,7 @@ module SBSM
117
116
  SBSM.debug "file_name is #{file_name} checkin base #{File.basename(file_name)} MIME #{mime_type}"
118
117
  response.set_header('Content-Type', mime_type)
119
118
  response.write(File.open(file_name, File::RDONLY){|file| file.read})
120
- return response
119
+ return response.finish
121
120
  end
122
121
 
123
122
  return [400, {}, []] if /favicon.ico/i.match(request.path)
@@ -127,15 +126,17 @@ module SBSM
127
126
  res = session.process_rack(rack_request: request)
128
127
  thru = session.get_passthru
129
128
  if thru.size > 0
130
- file_name = thru.first.untaint
131
- response.set_header('Content-Type', MimeMagic.by_extension(File.extname(file_name)).type)
132
- response.headers['Content-Disposition'] = "#{thru.last}; filename=#{File.basename(file_name)}"
133
- response.headers['Content-Length'] = File.size(file_name).to_s
134
129
  begin
130
+ file_name = thru.first
131
+ raise Errno::ENOENT unless File.exist?(file_name)
132
+ response.set_header('Content-Type', MimeMagic.by_extension(File.extname(file_name)).type)
133
+ response.headers['Content-Disposition'] = "#{thru.last}; filename=#{File.basename(file_name)}"
134
+ response.headers['Content-Length'] = File.size(file_name).to_s
135
135
  response.write(File.open(file_name, File::RDONLY){|file| file.read})
136
136
  rescue Errno::ENOENT, IOError => err
137
- SBSM.error("#{err.message} #{thru.first}")
138
- return [404, {}, []]
137
+ error_msg = "#{file_name} Not found\n"
138
+ SBSM.error("#{err.message} #{thru.first} => #{error_msg}")
139
+ return [404, {'Content-Type' => 'text/html', 'Content-Length' => error_msg.size.to_s}, [error_msg]]
139
140
  end
140
141
  else
141
142
  response.write res unless request.request_method.eql?('HEAD')
@@ -163,5 +164,9 @@ module SBSM
163
164
  response.finish
164
165
  end
165
166
 
167
+ private
168
+ def self.last_session # for unit tests only
169
+ @@last_session
170
+ end
166
171
  end
167
172
  end
File without changes
@@ -54,7 +54,8 @@ module SBSM
54
54
  self::class::HTML_ATTRIBUTES.fetch(key.to_sym, {}).dup rescue {}
55
55
  end
56
56
  def base_url
57
- [@session.http_protocol + ':/', @session.server_name, @language, @flavor].compact.join("/")
57
+ maybe_port = @session.server_port ? (":" + @session.server_port ) : ''
58
+ [@session.http_protocol + ':/', @session.server_name + maybe_port, @language, @flavor].compact.join("/")
58
59
  end
59
60
  def direct_event
60
61
  @session.direct_event
@@ -88,7 +89,7 @@ module SBSM
88
89
  @languages ||= self::class::DICTIONARIES.keys.sort
89
90
  end
90
91
  def language_url(language)
91
- [@session.http_protocol + ':/', @session.server_name, language, @flavor].compact.join("/")
92
+ base_url
92
93
  end
93
94
  def lookup(key, *args, &block)
94
95
  _lookup(key, *args) || (block.call if block)
@@ -166,9 +167,8 @@ module SBSM
166
167
  end
167
168
  end
168
169
  def _collect_resource(base, part, rstr)
169
- [ @session.http_protocol + ':/',
170
- @session.server_name,
171
- base, part, rstr].flatten.compact.join('/')
170
+ maybe_port = @session.server_port ? (":" + @session.server_port ) : ''
171
+ [ @session.http_protocol + ':/', @session.server_name + maybe_port, base, part, rstr].flatten.compact.join('/')
172
172
  end
173
173
  def set_dictionary(language)
174
174
  @dictionary = self::class::DICTIONARIES[language] || {}
@@ -213,7 +213,6 @@ module SBSM
213
213
  @rack_request = rack_request
214
214
  @request_path ||= rack_request.path
215
215
  @post_content = nil
216
-
217
216
  if rack_request.request_method.eql?('POST')
218
217
  rack_request.params.each do |k, v|
219
218
  # needed to test POST requests generated by curl (first parameter) or ARC (second parameter)
@@ -463,7 +462,7 @@ module SBSM
463
462
  {'Content-Type' => 'text/plain'}
464
463
  end
465
464
  def http_protocol
466
- @http_protocol ||= if(@server_port && @server_port == 443) || ENV['SERVER_PORT']
465
+ @http_protocol ||= if(@server_port && @server_port.to_i == 443) || ENV['SERVER_PORT']
467
466
  'https'
468
467
  else
469
468
  'http'
@@ -480,7 +479,7 @@ module SBSM
480
479
  end
481
480
  def passthru(path, disposition='attachment')
482
481
  # the variable @passthru is set by a trusted source
483
- @passthru = path.untaint
482
+ @passthru = path
484
483
  @disposition = disposition
485
484
  ''
486
485
  end
@@ -518,6 +517,13 @@ module SBSM
518
517
  @remote_ip ||= if(@request.respond_to?(:remote_host))
519
518
  @request.remote_host
520
519
  end
520
+ if @remote_ip.to_s.index(',')
521
+ saved = @remote_ip.clone
522
+ @remote_ip = @remote_ip.first if @remote_ip.is_a?(Array)
523
+ @remote_ip = @remote_ip.split(',').first.gsub(/[\[\]]/, '') if @remote_ip.is_a?(String)
524
+ SBSM.info("remote_ip is weird #{saved.inspect} => #{@remote_ip.inspect}")
525
+ end
526
+ @remote_ip
521
527
  end
522
528
  def set_cookie_input(key, val)
523
529
  SBSM.debug"set_cookie_input #{key} #{val}"
@@ -112,7 +112,7 @@ module SBSM
112
112
  end
113
113
  end
114
114
  seconds = (Time.now.to_i - now.to_i)
115
- SBSM.warn sprintf("Cleaned #{old_size - @@sessions.size} sessions. Took %d seconds", seconds)
115
+ # SBSM.warn sprintf("Cleaned #{old_size - @@sessions.size} sessions. Took %d seconds", seconds)
116
116
  end
117
117
  def SessionStore.sessions
118
118
  @@sessions
@@ -135,7 +135,8 @@ module SBSM
135
135
  def http_headers
136
136
  return @http_headers if @http_headers
137
137
  name = view
138
- name ? view.http_headers : {}
138
+ result = name ? view.http_headers : {}
139
+ result
139
140
  end
140
141
  def info?
141
142
  !@infos.empty?
@@ -44,13 +44,13 @@ module SBSM
44
44
  def initialize(name: nil, config_file: nil, handler_uri: nil)
45
45
  @handler_uri = handler_uri ||= '/index.rbx'
46
46
  config_file ||= 'etc/trans_handler.yml'
47
- @config_file = File.expand_path(config_file).untaint
47
+ @config_file = File.expand_path(config_file)
48
48
  @parser_name = name ||= 'uri'
49
49
  @parser_method = "_#{name}_parser"
50
50
  @grammar_path = File.expand_path("../../data/#{name}.grammar",
51
- File.dirname(__FILE__).untaint)
51
+ File.dirname(__FILE__))
52
52
  @parser_path = File.expand_path("#{name}_parser.rb",
53
- File.dirname(__FILE__).untaint)
53
+ File.dirname(__FILE__))
54
54
  end
55
55
  def config(request)
56
56
  config = Hash.new { {} }
@@ -150,12 +150,12 @@ module SBSM
150
150
  end
151
151
  def uri_parser(grammar_path=@grammar_path, parser_path=@parser_path)
152
152
  if(File.exist?(grammar_path))
153
- oldpath = File.expand_path("_" << File.basename(grammar_path),
153
+ oldpath = File.expand_path("_" << File.basename(grammar_path),
154
154
  File.dirname(grammar_path))
155
155
  src = File.read(grammar_path)
156
156
  unless(File.exists?(oldpath) && File.read(oldpath)==src)
157
157
  File.delete(oldpath) if File.exists?(oldpath)
158
- Parse.generate_parser_from_file_to_file(grammar_path,
158
+ Parse.generate_parser_from_file_to_file(grammar_path,
159
159
  parser_path, @parser_method, 'SBSM')
160
160
  File.open(oldpath, 'w') { |f| f << src }
161
161
  end
File without changes
@@ -1,3 +1,3 @@
1
1
  module SBSM
2
- VERSION = '1.5.5'
2
+ VERSION = '1.6.0'
3
3
  end
@@ -69,15 +69,20 @@ module Demo
69
69
  info.join("\n")
70
70
  end
71
71
  end
72
+ class AboutView
73
+ def initialize(model, session)
74
+ end
75
+ def to_html(cgi)
76
+ 'About SBSM: TDD ist great!'
77
+ end
78
+ end
72
79
  class AboutState < GlobalState
73
80
  DIRECT_EVENT = :about
81
+ VIEW = AboutView
74
82
  def initialize(session, user)
75
83
  SBSM.info "AboutState #{session}"
76
84
  super(session, user)
77
85
  end
78
- def to_html(cgi)
79
- 'About SBSM: TDD ist great!'
80
- end
81
86
  end
82
87
  class RedirectState < GlobalState
83
88
  DIRECT_EVENT = :redirect
@@ -239,4 +244,4 @@ module Demo
239
244
  session_class: session_class)
240
245
  end
241
246
  end
242
- end
247
+ end
@@ -7,6 +7,7 @@ ENV['RACK_ENV'] = 'test'
7
7
  ENV['REQUEST_METHOD'] = 'GET'
8
8
 
9
9
  require 'minitest/autorun'
10
+ require 'flexmock/minitest'
10
11
  require 'rack/test'
11
12
  require 'sbsm/app'
12
13
  require 'sbsm/session'
@@ -55,6 +56,67 @@ class AppVariantTest < Minitest::Test
55
56
  assert last_response.body.empty?
56
57
  assert last_response.headers.keys.index('Content-Type')
57
58
  end
59
+ def test_request_file
60
+ session_id_mock = '1234'
61
+ invalid_path = '/path/to/non/existing/file'
62
+
63
+ @app = flexmock('file_app', @app)
64
+ env = { 'HTTP_COOKIE' => "_session_id=#{session_id_mock}" }
65
+ session_store = SBSM::SessionStore.new(app: @app)
66
+ session_mock= flexmock('session', session_store[session_id_mock.to_s])
67
+ session_mock.should_receive(:get_passthru).and_return([invalid_path])
68
+ @app.should_receive(:session_store).and_return(session_store)
69
+
70
+ result = get invalid_path, {}, env
71
+
72
+ assert_equal(false, last_response.ok?)
73
+ assert_equal(404, last_response.status)
74
+ assert (last_response.body.to_s.index(invalid_path))
75
+ assert last_response.headers.keys.index('Content-Type')
76
+ assert_equal('text/html', last_response.headers['Content-Type'])
77
+ end
78
+ def test_request_file_with_no_mime_info
79
+ session_id_mock = '1234'
80
+ invalid_path = '/window.js.map.dummy'
81
+ file_name = File.expand_path(File.join('doc', invalid_path))
82
+ FileUtils.makedirs(File.dirname(file_name))
83
+ File.open(file_name, 'w+') {|f| f.puts 'dummy'}
84
+
85
+ @app = flexmock('file_app', @app)
86
+ env = { 'HTTP_COOKIE' => "_session_id=#{session_id_mock}" }
87
+ session_store = SBSM::SessionStore.new(app: @app)
88
+ session_mock= flexmock('session', session_store[session_id_mock.to_s])
89
+ session_mock.should_receive(:get_passthru).and_return([invalid_path])
90
+ @app.should_receive(:session_store).and_return(session_store)
91
+
92
+ result = get invalid_path, {}, env
93
+
94
+ assert_equal(true, last_response.ok?)
95
+ assert last_response.headers.keys.index('Content-Type')
96
+ assert_equal('text/plain', last_response.headers['Content-Type'])
97
+ FileUtils.rm(file_name)
98
+ end
99
+ def test_request_file_with_mime_info
100
+ session_id_mock = '1234'
101
+ invalid_path = '/window.png'
102
+ file_name = File.expand_path(File.join('doc', invalid_path))
103
+ FileUtils.makedirs(File.dirname(file_name))
104
+ File.open(file_name, 'w+') {|f| f.puts 'dummy'}
105
+
106
+ @app = flexmock('file_app', @app)
107
+ env = { 'HTTP_COOKIE' => "_session_id=#{session_id_mock}" }
108
+ session_store = SBSM::SessionStore.new(app: @app)
109
+ session_mock= flexmock('session', session_store[session_id_mock.to_s])
110
+ session_mock.should_receive(:get_passthru).and_return([invalid_path])
111
+ @app.should_receive(:session_store).and_return(session_store)
112
+
113
+ result = get invalid_path, {}, env
114
+
115
+ assert_equal(true, last_response.ok?)
116
+ assert last_response.headers.keys.index('Content-Type')
117
+ assert_equal('image/png', last_response.headers['Content-Type'])
118
+ FileUtils.rm(file_name)
119
+ end
58
120
  end
59
121
 
60
122
  class AppTestSimple < Minitest::Test
@@ -113,6 +175,7 @@ class AppTestSimple < Minitest::Test
113
175
  get '/sbsm.css'
114
176
  assert last_response.ok?
115
177
  assert_match css_content, last_response.body
178
+ FileUtils.rm(css_file)
116
179
  end
117
180
  def test_session_about_then_home
118
181
  skip ('TODO: We should test test_post_feedback')
@@ -16,19 +16,27 @@ RUN_ALL_TESTS=true unless defined?(RUN_ALL_TESTS)
16
16
 
17
17
  # Overriding some stuff from the simple_sbsm
18
18
  module Demo
19
+ class View_AboutState
20
+ def initialize(model, session)
21
+ end
22
+ def http_headers
23
+ { "foo" => "bar" }
24
+ end
25
+ def to_html(cgi)
26
+ "<br>customized to_html<br>"
27
+ end
28
+ end
29
+
19
30
  class AboutState < GlobalState
20
31
  DIRECT_EVENT = :about
32
+ VIEW = View_AboutState
21
33
  def initialize(session, user)
22
34
  SBSM.info "AboutState #{session}"
23
35
  super(session, user)
24
36
  session.login
25
37
  end
26
- def http_headers
27
- { "foo" => "bar" }
28
- end
29
38
  end
30
39
 
31
-
32
40
  DEMO_PERSISTENT_COOKIE_NAME = 'demo-simple-sbsm'
33
41
  class Demo::CustomizedSBSM_COOKIE < SBSM::App
34
42
  PERSISTENT_COOKIE_NAME = DEMO_PERSISTENT_COOKIE_NAME
@@ -201,6 +209,7 @@ class CustomizedAppSessionValidatorLnf < Minitest::Test
201
209
  end
202
210
  assert last_response.ok?
203
211
  assert_equal 'bar', last_response.headers['foo']
212
+ assert_equal '<br>customized to_html<br>', last_response.body
204
213
  end
205
214
 
206
215
  def test_process_state
@@ -69,6 +69,9 @@ class StubLookandfeelSession
69
69
  def flavor
70
70
  "gcc"
71
71
  end
72
+ def server_port
73
+ "1234"
74
+ end
72
75
  def server_name
73
76
  "test.com"
74
77
  end
@@ -127,7 +130,7 @@ class TestLookandfeel < Minitest::Test
127
130
  assert_equal({}, @lookandfeel.attributes(:undefined))
128
131
  end
129
132
  def test_resource
130
- assert_equal('http://test.com/resources/gcc/bar', @lookandfeel.resource(:foo))
133
+ assert_equal('http://test.com:1234/resources/gcc/bar', @lookandfeel.resource(:foo))
131
134
  end
132
135
  def test_lookup
133
136
  assert_equal('dictbar', @lookandfeel.lookup(:foo))
@@ -161,18 +164,18 @@ class TestLookandfeel < Minitest::Test
161
164
  assert_equal(expected, time.rfc1123)
162
165
  end
163
166
  def test_base_url
164
- assert_equal("http://test.com/de/gcc", @lookandfeel.base_url)
167
+ assert_equal("http://test.com:1234/de/gcc", @lookandfeel.base_url)
165
168
  end
166
169
  def test_event_url
167
- assert_match(/http:\/\/test.com\/de\/gcc\/foo\/state_id\/\d\/bar\/baz/,@lookandfeel.event_url(:foo, {:bar => 'baz'}))
170
+ assert_match(/http:\/\/test.com:1234\/de\/gcc\/foo\/state_id\/\d\/bar\/baz/,@lookandfeel.event_url(:foo, {:bar => 'baz'}))
168
171
  end
169
172
  def test_event_url__crawler
170
173
  @session.is_crawler = true
171
- assert_equal("http://test.com/de/gcc/foo/bar/baz",
174
+ assert_equal("http://test.com:1234/de/gcc/foo/bar/baz",
172
175
  @lookandfeel.event_url(:foo, {:bar => 'baz'}))
173
176
  end
174
177
  def test_event_url__state_id_given
175
- assert_equal("http://test.com/de/gcc/foo/bar/baz/state_id/mine",
178
+ assert_equal("http://test.com:1234/de/gcc/foo/bar/baz/state_id/mine",
176
179
  @lookandfeel.event_url(:foo, [:bar, 'baz', :state_id, 'mine']))
177
180
  end
178
181
  def test_format_price
@@ -214,10 +217,10 @@ class TestLookandfeelWrapper < Minitest::Test
214
217
  end
215
218
  def test_resource1
216
219
  lnf = SBSM::LookandfeelWrapper.new(@lookandfeel)
217
- assert_equal('http://test.com/resources/gcc/bar', lnf.resource(:foo))
220
+ assert_equal('http://test.com:1234/resources/gcc/bar', lnf.resource(:foo))
218
221
  end
219
222
  def test_resource2
220
- assert_equal('http://test.com/resources/gcc/foo', @wrapped.resource(:foo))
223
+ assert_equal('http://test.com:1234/resources/gcc/foo', @wrapped.resource(:foo))
221
224
  end
222
225
  def test_attributes1
223
226
  lnf = SBSM::LookandfeelWrapper.new(@lookandfeel)
@@ -142,6 +142,23 @@ class StubSessionSession < SBSM::Session
142
142
  end
143
143
  end
144
144
 
145
+ class TestSessionApp < Minitest::Test
146
+ include Rack::Test::Methods
147
+ # attr_reader :app
148
+ def app
149
+ app = SBSM::RackInterface.new(app: SBSM::App)
150
+ builder = Rack::Builder.new
151
+ builder.run app
152
+ end
153
+ def test_request_remote_ip
154
+ get '/'
155
+ assert_nil SBSM::RackInterface.last_session.remote_ip
156
+ header 'X_FORWARDED_FOR', '[212.51.146.241],[66.249.93.27]' # a HTTP_ will be prepended to it
157
+ get '/'
158
+ assert_equal '212.51.146.241', SBSM::RackInterface.last_session.remote_ip
159
+ end
160
+ end
161
+
145
162
  class TestSession < Minitest::Test
146
163
  include Rack::Test::Methods
147
164
  def setup
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sbsm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.5
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masaomi Hatakeyama, Zeno R.R. Davatz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-07-12 00:00:00.000000000 Z
11
+ date: 2020-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -331,8 +331,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
331
331
  - !ruby/object:Gem::Version
332
332
  version: '0'
333
333
  requirements: []
334
- rubyforge_project:
335
- rubygems_version: 2.6.8
334
+ rubygems_version: 3.1.2
336
335
  signing_key:
337
336
  specification_version: 4
338
337
  summary: Application framework for state based session management from ywesee