tynn 1.0.0.rc2 → 1.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,32 @@
1
+ require_relative "../lib/tynn/force_ssl"
2
+
3
+ setup do
4
+ Tynn::Test.new
5
+ end
6
+
7
+ test "redirects to https" do |app|
8
+ Tynn.helpers(Tynn::ForceSSL)
9
+
10
+ Tynn.define do
11
+ end
12
+
13
+ app.get("/")
14
+
15
+ assert_equal 301, app.res.status
16
+ assert_equal "https://example.org/", app.res.location
17
+ end
18
+
19
+ test "https request" do |app|
20
+ Tynn.helpers(Tynn::ForceSSL)
21
+
22
+ Tynn.define do
23
+ root do
24
+ res.write("secure")
25
+ end
26
+ end
27
+
28
+ app.get("/", {}, "HTTPS" => "on")
29
+
30
+ assert_equal 200, app.res.status
31
+ assert_equal "secure", app.res.body
32
+ end
@@ -0,0 +1,78 @@
1
+ require_relative "../lib/tynn/hmote"
2
+
3
+ setup do
4
+ Tynn.helpers(Tynn::HMote, views: File.expand_path("./test/views"))
5
+
6
+ Tynn::Test.new
7
+ end
8
+
9
+ test "partial" do |app|
10
+ Tynn.define do
11
+ on "partial" do
12
+ res.write(partial("partial", name: "mote"))
13
+ end
14
+ end
15
+
16
+ app.get("/partial")
17
+
18
+ assert_equal "mote", app.res.body.strip
19
+ end
20
+
21
+ test "view" do |app|
22
+ Tynn.define do
23
+ on "view" do
24
+ res.write(view("view", title: "tynn", name: "mote"))
25
+ end
26
+ end
27
+
28
+ app.get("/view")
29
+
30
+ assert_equal "tynn / mote", app.res.body.strip
31
+ end
32
+
33
+ test "render" do |app|
34
+ Tynn.define do
35
+ on "render" do
36
+ render("view", title: "tynn", name: "mote")
37
+ end
38
+ end
39
+
40
+ app.get("/render")
41
+
42
+ assert_equal 200, app.res.status
43
+ assert_equal "text/html", app.res.headers["Content-Type"]
44
+ assert_equal "tynn / mote", app.res.body.strip
45
+ end
46
+
47
+ test "404" do |app|
48
+ Tynn.define do
49
+ on "404" do
50
+ res.status = 404
51
+
52
+ render("view", title: "tynn", name: "mote")
53
+ end
54
+ end
55
+
56
+ app.get("/404")
57
+
58
+ assert_equal 404, app.res.status
59
+ assert_equal "text/html", app.res.headers["Content-Type"]
60
+ assert_equal "tynn / mote", app.res.body.strip
61
+ end
62
+
63
+ test "custom layout" do
64
+ class App < Tynn
65
+ set(:layout, "custom_layout")
66
+ end
67
+
68
+ App.define do
69
+ root do
70
+ render("view", title: "tynn", name: "mote")
71
+ end
72
+ end
73
+
74
+ app = Tynn::Test.new(App)
75
+ app.get("/")
76
+
77
+ assert_equal "custom / tynn / mote", app.res.body.strip
78
+ end
data/test/hsts_test.rb ADDED
@@ -0,0 +1,29 @@
1
+ require_relative "../lib/tynn/hsts"
2
+
3
+ test "hsts header" do |app|
4
+ Tynn.helpers(Tynn::HSTS)
5
+
6
+ Tynn.define do
7
+ end
8
+
9
+ app = Tynn::Test.new
10
+ app.get("/", {})
11
+
12
+ header = app.res.headers["Strict-Transport-Security"]
13
+
14
+ assert_equal "max-age=15552000; includeSubdomains", header
15
+ end
16
+
17
+ test "hsts header options" do |app|
18
+ Tynn.helpers(Tynn::HSTS, expires: 1, subdomains: false, preload: true)
19
+
20
+ Tynn.define do
21
+ end
22
+
23
+ app = Tynn::Test.new
24
+ app.get("/", {})
25
+
26
+ header = app.res.headers["Strict-Transport-Security"]
27
+
28
+ assert_equal "max-age=1; preload", header
29
+ end
@@ -1,18 +1,6 @@
1
1
  require_relative "../lib/tynn/protection"
2
2
  require_relative "../lib/tynn/session"
3
3
 
4
- test "includes secure headers" do
5
- Tynn.helpers(Tynn::Protection)
6
-
7
- assert Tynn.include?(Tynn::SecureHeaders)
8
- end
9
-
10
- test "includes ssl helper if ssl is true" do
11
- Tynn.helpers(Tynn::Protection, ssl: true)
12
-
13
- assert Tynn.include?(Tynn::SSL)
14
- end
15
-
16
4
  test "supports hsts options" do
17
5
  hsts = { expires: 100, subdomains: false, preload: true }
18
6
 
@@ -46,21 +34,3 @@ test "adds secure flag to session cookie" do
46
34
 
47
35
  assert(/;\s*secure\s*(;|$)/i === session)
48
36
  end
49
-
50
- test "if session uses secure flag" do
51
- Tynn.helpers(Tynn::Protection, ssl: true)
52
- Tynn.helpers(Tynn::Session, secret: "_this_must_be_random_", secure: true)
53
-
54
- Tynn.define do
55
- root do
56
- session[:foo] = "foo"
57
- end
58
- end
59
-
60
- app = Tynn::Test.new
61
- app.get("/", {}, "HTTPS" => "on")
62
-
63
- session, _ = app.res.headers["Set-Cookie"].split("\n")
64
-
65
- assert(/;\s*secure\s*(;|$)/i === session)
66
- end
data/test/render_test.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "erb"
1
+ require "erubis"
2
2
  require_relative "../lib/tynn/render"
3
3
 
4
4
  setup do
@@ -77,3 +77,16 @@ test "custom layout" do
77
77
 
78
78
  assert_equal "custom / tynn / erb", app.res.body.strip
79
79
  end
80
+
81
+ test "escapes by default" do
82
+ Tynn.define do
83
+ root do
84
+ res.write(partial("partial", name: "<a></a>"))
85
+ end
86
+ end
87
+
88
+ app = Tynn::Test.new
89
+ app.get("/")
90
+
91
+ assert_equal "&lt;a&gt;&lt;/a&gt;", app.res.body.strip
92
+ end
@@ -12,9 +12,16 @@ test "secure headers" do
12
12
  app = Tynn::Test.new
13
13
  app.get("/")
14
14
 
15
+ secure_headers = {
16
+ "X-Content-Type-Options" => "nosniff",
17
+ "X-Frame-Options" => "SAMEORIGIN",
18
+ "X-Permitted-Cross-Domain-Policies" => "none",
19
+ "X-XSS-Protection" => "1; mode=block"
20
+ }
21
+
15
22
  headers = app.res.headers
16
23
 
17
- Tynn::SecureHeaders::HEADERS.each do |header, value|
24
+ secure_headers.each do |header, value|
18
25
  assert_equal(value, headers[header])
19
26
  end
20
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tynn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc2
4
+ version: 1.0.0.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Francesco Rodríguez
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-21 00:00:00.000000000 Z
11
+ date: 2015-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
- - !ruby/object:Gem::Dependency
28
- name: seteable
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '1.1'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '1.1'
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: syro
43
29
  requirement: !ruby/object:Gem::Requirement
@@ -134,7 +120,9 @@ files:
134
120
  - lib/tynn.rb
135
121
  - lib/tynn/all_methods.rb
136
122
  - lib/tynn/environment.rb
137
- - lib/tynn/erubis.rb
123
+ - lib/tynn/force_ssl.rb
124
+ - lib/tynn/hmote.rb
125
+ - lib/tynn/hsts.rb
138
126
  - lib/tynn/json.rb
139
127
  - lib/tynn/matchers.rb
140
128
  - lib/tynn/not_found.rb
@@ -144,15 +132,18 @@ files:
144
132
  - lib/tynn/response.rb
145
133
  - lib/tynn/secure_headers.rb
146
134
  - lib/tynn/session.rb
147
- - lib/tynn/ssl.rb
135
+ - lib/tynn/settings.rb
148
136
  - lib/tynn/static.rb
149
137
  - lib/tynn/test.rb
150
138
  - lib/tynn/version.rb
151
139
  - test/all_methods_test.rb
152
140
  - test/core_test.rb
141
+ - test/default_headers_test.rb
153
142
  - test/environment_test.rb
154
- - test/erubis_test.rb
143
+ - test/force_ssl_test.rb
155
144
  - test/helper.rb
145
+ - test/hmote_test.rb
146
+ - test/hsts_test.rb
156
147
  - test/json_test.rb
157
148
  - test/matchers_test.rb
158
149
  - test/middleware_test.rb
@@ -161,7 +152,6 @@ files:
161
152
  - test/render_test.rb
162
153
  - test/secure_headers_test.rb
163
154
  - test/session_test.rb
164
- - test/ssl_test.rb
165
155
  - test/static_test.rb
166
156
  homepage: https://github.com/frodsan/tynn
167
157
  licenses:
@@ -190,9 +180,12 @@ summary: Thin library to create web applications
190
180
  test_files:
191
181
  - test/all_methods_test.rb
192
182
  - test/core_test.rb
183
+ - test/default_headers_test.rb
193
184
  - test/environment_test.rb
194
- - test/erubis_test.rb
185
+ - test/force_ssl_test.rb
195
186
  - test/helper.rb
187
+ - test/hmote_test.rb
188
+ - test/hsts_test.rb
196
189
  - test/json_test.rb
197
190
  - test/matchers_test.rb
198
191
  - test/middleware_test.rb
@@ -201,5 +194,5 @@ test_files:
201
194
  - test/render_test.rb
202
195
  - test/secure_headers_test.rb
203
196
  - test/session_test.rb
204
- - test/ssl_test.rb
205
197
  - test/static_test.rb
198
+ has_rdoc:
data/lib/tynn/erubis.rb DELETED
@@ -1,17 +0,0 @@
1
- require "erubis"
2
- require_relative "render"
3
-
4
- class Tynn
5
- module Erubis
6
- def self.setup(app, options = {}) # :nodoc:
7
- options = options.dup
8
-
9
- options[:options] ||= {}
10
- options[:options] = {
11
- escape_html: true
12
- }.merge!(options[:options])
13
-
14
- app.helpers(Tynn::Render, options)
15
- end
16
- end
17
- end
data/lib/tynn/ssl.rb DELETED
@@ -1,73 +0,0 @@
1
- class Tynn
2
- module SSL
3
- def self.setup(app, hsts: {}) # :nodoc:
4
- app.use(Tynn::SSL::Middleware, hsts: hsts)
5
- end
6
-
7
- class Middleware # :nodoc:
8
- def initialize(app, hsts: {})
9
- @app = app
10
- @hsts_header = build_hsts_header(hsts)
11
- end
12
-
13
- def call(env)
14
- request = Rack::Request.new(env)
15
-
16
- unless request.ssl?
17
- return [301, redirect_headers(request), []]
18
- end
19
-
20
- result = @app.call(env)
21
-
22
- set_hsts_header(result[1])
23
- set_cookies_as_secure(result[1])
24
-
25
- return result
26
- end
27
-
28
- private
29
-
30
- HSTS_HEADER = "Strict-Transport-Security".freeze
31
- HSTS_EXPIRE = 15_552_000 # 180 days
32
-
33
- def build_hsts_header(options)
34
- header = sprintf("max-age=%i", options.fetch(:expires, HSTS_EXPIRE))
35
- header << "; includeSubdomains" if options.fetch(:subdomains, true)
36
- header << "; preload" if options[:preload]
37
-
38
- return header
39
- end
40
-
41
- def redirect_headers(request)
42
- return {
43
- "Content-Type" => "text/html",
44
- "Location" => https_location(request)
45
- }
46
- end
47
-
48
- HTTPS_LOCATION = "https://%s%s".freeze
49
-
50
- def https_location(request)
51
- return sprintf(HTTPS_LOCATION, request.host, request.fullpath)
52
- end
53
-
54
- def set_hsts_header(headers)
55
- headers[HSTS_HEADER] = @hsts_header
56
- end
57
-
58
- COOKIE_HEADER = "Set-Cookie".freeze
59
- COOKIE_SEPARATOR = "\n".freeze
60
- COOKIE_REGEXP = /;\s*secure\s*(;|$)/i
61
-
62
- def set_cookies_as_secure(headers)
63
- return unless cookies = headers[COOKIE_HEADER]
64
-
65
- cookies = cookies.split(COOKIE_SEPARATOR).map do |cookie|
66
- (cookie !~ COOKIE_REGEXP) ? "#{ cookie }; secure" : cookie
67
- end
68
-
69
- headers[COOKIE_HEADER] = cookies.join(COOKIE_SEPARATOR)
70
- end
71
- end
72
- end
73
- end
data/test/erubis_test.rb DELETED
@@ -1,20 +0,0 @@
1
- require_relative "../lib/tynn/erubis"
2
-
3
- setup do
4
- Tynn.helpers(Tynn::Erubis, views: File.expand_path("./test/views"))
5
-
6
- Tynn::Test.new
7
- end
8
-
9
- test "escapes" do |app|
10
- Tynn.define do
11
- root do
12
- res.write(partial("partial", name: "<a></a>"))
13
- end
14
- end
15
-
16
- app = Tynn::Test.new
17
- app.get("/")
18
-
19
- assert_equal "&lt;a&gt;&lt;/a&gt;", app.res.body.strip
20
- end
data/test/ssl_test.rb DELETED
@@ -1,82 +0,0 @@
1
- require_relative "../lib/tynn/ssl"
2
-
3
- setup do
4
- Tynn::Test.new
5
- end
6
-
7
- test "redirects to https" do |app|
8
- Tynn.helpers(Tynn::SSL)
9
-
10
- Tynn.define do
11
- end
12
-
13
- app.get("/")
14
-
15
- assert_equal 301, app.res.status
16
- assert_equal "https://example.org/", app.res.location
17
- end
18
-
19
- test "https request" do |app|
20
- Tynn.helpers(Tynn::SSL)
21
-
22
- Tynn.define do
23
- root do
24
- res.write("secure")
25
- end
26
- end
27
-
28
- app.get("/", {}, "HTTPS" => "on")
29
-
30
- assert_equal "secure", app.res.body
31
- end
32
-
33
- test "hsts header" do |app|
34
- Tynn.helpers(Tynn::SSL)
35
-
36
- Tynn.define do
37
- end
38
-
39
- app = Tynn::Test.new
40
- app.get("/", {}, "HTTPS" => "on")
41
-
42
- header = app.res.headers["Strict-Transport-Security"]
43
-
44
- assert_equal "max-age=15552000; includeSubdomains", header
45
- end
46
-
47
- test "hsts header options" do |app|
48
- Tynn.helpers(Tynn::SSL, hsts: {
49
- expires: 1,
50
- subdomains: false,
51
- preload: true
52
- })
53
-
54
- Tynn.define do
55
- end
56
-
57
- app = Tynn::Test.new
58
- app.get("/", {}, "HTTPS" => "on")
59
-
60
- header = app.res.headers["Strict-Transport-Security"]
61
-
62
- assert_equal "max-age=1; preload", header
63
- end
64
-
65
- test "secure cookies" do |app|
66
- Tynn.helpers(Tynn::SSL)
67
-
68
- Tynn.define do
69
- get do
70
- res.set_cookie("first", "cookie")
71
- res.set_cookie("other", "cookie")
72
- end
73
- end
74
-
75
- app = Tynn::Test.new
76
- app.get("/", {}, "HTTPS" => "on")
77
-
78
- first, other = app.res.headers["Set-Cookie"].split("\n")
79
-
80
- assert_equal "first=cookie; secure", first
81
- assert_equal "other=cookie; secure", other
82
- end