utopia 2.7.0 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -2
- data/bin/utopia +2 -2
- data/lib/utopia/command/server.rb +10 -6
- data/lib/utopia/command/site.rb +9 -5
- data/lib/utopia/command.rb +9 -8
- data/lib/utopia/session/serialization.rb +48 -0
- data/lib/utopia/session.rb +28 -11
- data/lib/utopia/version.rb +1 -1
- data/utopia.gemspec +2 -1
- metadata +20 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 477858ba9b55a11f0f5736f0e354b93ca411a7df255729f9e9d26aa35cad1553
|
4
|
+
data.tar.gz: 3429ad6e6a28e5ea03f6258a494a9e5c091cfa79862d1a984d861b9c2353f271
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f0197e55bebe111947c04b36e5e3285edc8d4df58ffbf2f0e3e37b81fe813b7ae0eef18d75050bee3f90e43cb70e273ebae9c403650adaf88b69db943f2e92d5
|
7
|
+
data.tar.gz: da791eaebbac5ff5d77ed69e6cc8d4c2b3600a27b483d211e1ab8c17f74bd9e50ed63f9cb16d32abd5b89219e09c2291a43eb74c89ced7c73c0ec57b73538a07
|
data/Gemfile
CHANGED
data/bin/utopia
CHANGED
@@ -32,12 +32,12 @@ module Utopia
|
|
32
32
|
class Create < Samovar::Command
|
33
33
|
self.description = "Create a remote Utopia website suitable for deployment using git."
|
34
34
|
|
35
|
-
def
|
35
|
+
def call
|
36
36
|
destination_root = parent.root
|
37
37
|
|
38
38
|
FileUtils.mkdir_p File.join(destination_root, "public")
|
39
39
|
|
40
|
-
Update.
|
40
|
+
Update[parent: parent].call
|
41
41
|
|
42
42
|
# Print out helpful git remote add message:
|
43
43
|
hostname = `hostname`.chomp
|
@@ -55,7 +55,7 @@ module Utopia
|
|
55
55
|
File.join(SETUP_ROOT, 'server')
|
56
56
|
end
|
57
57
|
|
58
|
-
def
|
58
|
+
def call
|
59
59
|
destination_root = parent.root
|
60
60
|
|
61
61
|
Dir.chdir(destination_root) do
|
@@ -91,12 +91,16 @@ module Utopia
|
|
91
91
|
|
92
92
|
self.description = "Manage server deployments."
|
93
93
|
|
94
|
-
nested
|
94
|
+
nested :command,
|
95
95
|
'create' => Create,
|
96
96
|
'update' => Update
|
97
97
|
|
98
|
-
def
|
99
|
-
@
|
98
|
+
def root
|
99
|
+
@parent.root
|
100
|
+
end
|
101
|
+
|
102
|
+
def call
|
103
|
+
@command.call
|
100
104
|
end
|
101
105
|
end
|
102
106
|
end
|
data/lib/utopia/command/site.rb
CHANGED
@@ -46,7 +46,7 @@ module Utopia
|
|
46
46
|
class Create < Samovar::Command
|
47
47
|
self.description = "Create a new local Utopia website using the default template."
|
48
48
|
|
49
|
-
def
|
49
|
+
def call
|
50
50
|
destination_root = parent.root
|
51
51
|
|
52
52
|
$stderr.puts "Setting up initial site in #{destination_root} for Utopia v#{Utopia::VERSION}..."
|
@@ -135,7 +135,7 @@ module Utopia
|
|
135
135
|
end
|
136
136
|
end
|
137
137
|
|
138
|
-
def
|
138
|
+
def call
|
139
139
|
destination_root = parent.root
|
140
140
|
branch_name = "utopia-upgrade-#{Utopia::VERSION}"
|
141
141
|
|
@@ -195,14 +195,18 @@ module Utopia
|
|
195
195
|
end
|
196
196
|
end
|
197
197
|
|
198
|
-
nested
|
198
|
+
nested :command,
|
199
199
|
'create' => Create,
|
200
200
|
'update' => Update
|
201
201
|
|
202
202
|
self.description = "Manage local utopia sites."
|
203
203
|
|
204
|
-
def
|
205
|
-
@
|
204
|
+
def root
|
205
|
+
@parent.root
|
206
|
+
end
|
207
|
+
|
208
|
+
def call
|
209
|
+
@command.call
|
206
210
|
end
|
207
211
|
end
|
208
212
|
end
|
data/lib/utopia/command.rb
CHANGED
@@ -26,8 +26,8 @@ require_relative 'command/environment'
|
|
26
26
|
|
27
27
|
module Utopia
|
28
28
|
module Command
|
29
|
-
def self.
|
30
|
-
Top.
|
29
|
+
def self.call(*args)
|
30
|
+
Top.call(*args)
|
31
31
|
end
|
32
32
|
|
33
33
|
# The top level utopia command.
|
@@ -40,23 +40,24 @@ module Utopia
|
|
40
40
|
option '-v/--version', "Print out the application version."
|
41
41
|
end
|
42
42
|
|
43
|
-
nested
|
43
|
+
nested :command, {
|
44
44
|
'site' => Site,
|
45
45
|
'server' => Server,
|
46
46
|
'environment' => Environment
|
47
|
+
}
|
47
48
|
|
48
49
|
# The root directory for the site.
|
49
50
|
def root
|
50
51
|
File.expand_path(@options.fetch(:root, ''), Dir.getwd)
|
51
52
|
end
|
52
53
|
|
53
|
-
def
|
54
|
+
def call
|
54
55
|
if @options[:version]
|
55
|
-
puts "
|
56
|
-
elsif @options[:help]
|
57
|
-
print_usage(
|
56
|
+
puts "#{self.name} v#{VERSION}"
|
57
|
+
elsif @options[:help]
|
58
|
+
print_usage(output: $stdout)
|
58
59
|
else
|
59
|
-
@command.
|
60
|
+
@command.call
|
60
61
|
end
|
61
62
|
end
|
62
63
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Copyright, 2014, by Samuel G. D. Williams. <http://www.codeotaku.com>
|
2
|
+
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
20
|
+
|
21
|
+
require 'time'
|
22
|
+
require 'date'
|
23
|
+
|
24
|
+
module Utopia
|
25
|
+
class Session
|
26
|
+
class Serialization
|
27
|
+
def initialize
|
28
|
+
@factory = MessagePack::Factory.new
|
29
|
+
|
30
|
+
@factory.register_type(0x00, Symbol, packer: :to_msgpack_ext, unpacker: :from_msgpack_ext)
|
31
|
+
|
32
|
+
@factory.register_type(0x01, Time, packer: :iso8601, unpacker: :parse)
|
33
|
+
@factory.register_type(0x02, Date, packer: :iso8601, unpacker: :parse)
|
34
|
+
@factory.register_type(0x03, DateTime, packer: :iso8601, unpacker: :parse)
|
35
|
+
end
|
36
|
+
|
37
|
+
attr :factory
|
38
|
+
|
39
|
+
def load(data)
|
40
|
+
@factory.unpack(data)
|
41
|
+
end
|
42
|
+
|
43
|
+
def dump(object)
|
44
|
+
@factory.pack(object)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/utopia/session.rb
CHANGED
@@ -22,11 +22,19 @@ require 'openssl'
|
|
22
22
|
require 'securerandom'
|
23
23
|
require 'digest/sha2'
|
24
24
|
|
25
|
+
require 'json'
|
26
|
+
|
25
27
|
require_relative 'session/lazy_hash'
|
28
|
+
require_relative 'session/serialization'
|
26
29
|
|
27
30
|
module Utopia
|
28
31
|
# A middleware which provides a secure client-side session storage using a private symmetric encrpytion key.
|
29
32
|
class Session
|
33
|
+
class PayloadError < StandardError
|
34
|
+
end
|
35
|
+
|
36
|
+
MAXIMUM_SIZE = 1024*32
|
37
|
+
|
30
38
|
SECRET_KEY = 'UTOPIA_SESSION_SECRET'.freeze
|
31
39
|
|
32
40
|
RACK_SESSION = "rack.session".freeze
|
@@ -42,7 +50,7 @@ module Utopia
|
|
42
50
|
# @param secret [Array] The secret text used to generate a symetric encryption key for the coookie data.
|
43
51
|
# @param expires_after [String] The cache-control header to set for static content.
|
44
52
|
# @param options [Hash<Symbol,Object>] Additional defaults used for generating the cookie by `Rack::Utils.set_cookie_header!`.
|
45
|
-
def initialize(app, session_name: RACK_SESSION, secret: nil, expires_after: DEFAULT_EXPIRES_AFTER, update_timeout: DEFAULT_UPDATE_TIMEOUT, secure: false, **options)
|
53
|
+
def initialize(app, session_name: RACK_SESSION, secret: nil, expires_after: DEFAULT_EXPIRES_AFTER, update_timeout: DEFAULT_UPDATE_TIMEOUT, secure: false, maximum_size: MAXIMUM_SIZE, **options)
|
46
54
|
@app = app
|
47
55
|
|
48
56
|
@session_name = session_name
|
@@ -67,6 +75,9 @@ module Utopia
|
|
67
75
|
# The HttpOnly attribute directs browsers not to expose cookies through channels other than HTTP (and HTTPS) requests. This means that the cookie cannot be accessed via client-side scripting languages (notably JavaScript), and therefore cannot be stolen easily via cross-site scripting (a pervasive attack technique).
|
68
76
|
http_only: true,
|
69
77
|
}.merge(options)
|
78
|
+
|
79
|
+
@serialization = Serialization.new
|
80
|
+
@maximum_size = maximum_size
|
70
81
|
end
|
71
82
|
|
72
83
|
attr :cookie_name
|
@@ -135,8 +146,14 @@ module Utopia
|
|
135
146
|
|
136
147
|
# Decrypt the data from the user if possible:
|
137
148
|
if data = request.cookies[@cookie_name]
|
138
|
-
|
139
|
-
|
149
|
+
begin
|
150
|
+
if values = decrypt(data)
|
151
|
+
validate_session!(request, values)
|
152
|
+
|
153
|
+
return values
|
154
|
+
end
|
155
|
+
rescue => error
|
156
|
+
request.logger&.error(error)
|
140
157
|
end
|
141
158
|
end
|
142
159
|
|
@@ -144,11 +161,9 @@ module Utopia
|
|
144
161
|
return build_initial_session(request)
|
145
162
|
end
|
146
163
|
|
147
|
-
def
|
164
|
+
def validate_session!(request, values)
|
148
165
|
if values[:user_agent] != request.user_agent
|
149
|
-
|
150
|
-
|
151
|
-
return false
|
166
|
+
raise PayloadError, "Invalid session because supplied user agent #{request.user_agent.inspect} does not match session user agent #{values[:user_agent].inspect}!"
|
152
167
|
end
|
153
168
|
|
154
169
|
return true
|
@@ -177,13 +192,17 @@ module Utopia
|
|
177
192
|
c.key = @key
|
178
193
|
c.iv = iv = c.random_iv
|
179
194
|
|
180
|
-
e = c.update(
|
195
|
+
e = c.update(@serialization.dump(hash))
|
181
196
|
e << c.final
|
182
197
|
|
183
198
|
return [iv, e].pack("m16m*")
|
184
199
|
end
|
185
200
|
|
186
201
|
def decrypt(data)
|
202
|
+
if @maximum_size and data.bytesize > @maximum_size
|
203
|
+
raise PayloadError, "Session payload size #{data.bytesize}bytes exceeds maximum allowed size #{@maximum_size}bytes!"
|
204
|
+
end
|
205
|
+
|
187
206
|
iv, e = data.unpack("m16m*")
|
188
207
|
|
189
208
|
c = OpenSSL::Cipher.new(CIPHER_ALGORITHM)
|
@@ -195,9 +214,7 @@ module Utopia
|
|
195
214
|
d = c.update(e)
|
196
215
|
d << c.final
|
197
216
|
|
198
|
-
return
|
199
|
-
rescue
|
200
|
-
return nil
|
217
|
+
return @serialization.load(d)
|
201
218
|
end
|
202
219
|
end
|
203
220
|
end
|
data/lib/utopia/version.rb
CHANGED
data/utopia.gemspec
CHANGED
@@ -25,8 +25,9 @@ Gem::Specification.new do |spec|
|
|
25
25
|
|
26
26
|
spec.add_dependency 'trenni', '~> 3.0'
|
27
27
|
spec.add_dependency 'mime-types', '~> 3.0'
|
28
|
+
spec.add_dependency 'msgpack'
|
28
29
|
|
29
|
-
spec.add_dependency 'samovar', '~> 1
|
30
|
+
spec.add_dependency 'samovar', '~> 2.1'
|
30
31
|
spec.add_dependency 'event', '~> 1.1'
|
31
32
|
|
32
33
|
spec.add_dependency 'rack', '~> 2.0'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: utopia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trenni
|
@@ -38,20 +38,34 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '3.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: msgpack
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: samovar
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
44
58
|
requirements:
|
45
59
|
- - "~>"
|
46
60
|
- !ruby/object:Gem::Version
|
47
|
-
version: '1
|
61
|
+
version: '2.1'
|
48
62
|
type: :runtime
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '1
|
68
|
+
version: '2.1'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: event
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -584,6 +598,7 @@ files:
|
|
584
598
|
- lib/utopia/redirection.rb
|
585
599
|
- lib/utopia/session.rb
|
586
600
|
- lib/utopia/session/lazy_hash.rb
|
601
|
+
- lib/utopia/session/serialization.rb
|
587
602
|
- lib/utopia/setup.rb
|
588
603
|
- lib/utopia/static.rb
|
589
604
|
- lib/utopia/static/local_file.rb
|
@@ -745,7 +760,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
745
760
|
- !ruby/object:Gem::Version
|
746
761
|
version: '0'
|
747
762
|
requirements: []
|
748
|
-
rubygems_version: 3.0.
|
763
|
+
rubygems_version: 3.0.3
|
749
764
|
signing_key:
|
750
765
|
specification_version: 4
|
751
766
|
summary: Utopia is a framework for building dynamic content-driven websites.
|