camaleon_cms 2.4.3.5 → 2.4.3.6
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of camaleon_cms might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +5 -5
- data/app/apps/themes/camaleon_first/views/layouts/{mailer.html.erb → camaleon_cms/mailer.html.erb} +0 -0
- data/app/apps/themes/camaleon_first/views/{html_mailer/mailer.html.erb → mailer.html.erb} +0 -0
- data/app/assets/javascripts/camaleon_cms/admin/jquery.validate.js +3 -3
- data/app/assets/javascripts/camaleon_cms/admin/tinymce/langs/zh-CN.js +10 -1
- data/app/assets/stylesheets/camaleon_cms/admin/uploader/_uploadfile.css.scss +14 -2
- data/app/controllers/camaleon_cms/admin/appearances/nav_menus_controller.rb +4 -3
- data/app/controllers/camaleon_cms/admin/categories_controller.rb +3 -0
- data/app/controllers/camaleon_cms/admin/comments_controller.rb +1 -0
- data/app/controllers/camaleon_cms/admin/posts/drafts_controller.rb +1 -1
- data/app/controllers/camaleon_cms/admin/posts_controller.rb +21 -7
- data/app/controllers/camaleon_cms/admin/sessions_controller.rb +0 -2
- data/app/controllers/camaleon_cms/admin/settings_controller.rb +1 -1
- data/app/controllers/camaleon_cms/admin/users_controller.rb +14 -3
- data/app/controllers/camaleon_cms/frontend_controller.rb +1 -1
- data/app/controllers/concerns/camaleon_cms/frontend_concern.rb +4 -4
- data/app/decorators/camaleon_cms/application_decorator.rb +1 -1
- data/app/decorators/camaleon_cms/post_decorator.rb +2 -2
- data/app/decorators/camaleon_cms/post_type_decorator.rb +3 -1
- data/app/decorators/camaleon_cms/user_decorator.rb +4 -0
- data/app/helpers/camaleon_cms/admin/application_helper.rb +1 -1
- data/app/helpers/camaleon_cms/admin/custom_fields_helper.rb +8 -8
- data/app/helpers/camaleon_cms/admin/menus_helper.rb +1 -1
- data/app/helpers/camaleon_cms/camaleon_helper.rb +5 -0
- data/app/helpers/camaleon_cms/uploader_helper.rb +1 -1
- data/app/models/camaleon_cms/post.rb +13 -6
- data/app/models/camaleon_cms/post_type.rb +1 -1
- data/app/models/camaleon_cms/site.rb +1 -1
- data/app/models/camaleon_cms/user_role.rb +8 -0
- data/app/models/concerns/camaleon_cms/custom_fields_read.rb +9 -7
- data/app/models/concerns/camaleon_cms/user_methods.rb +11 -1
- data/app/uploaders/camaleon_cms_local_uploader.rb +4 -2
- data/app/uploaders/camaleon_cms_uploader.rb +1 -1
- data/app/views/camaleon_cms/admin/categories/index.html.erb +2 -2
- data/app/views/camaleon_cms/admin/post_tags/index.html.erb +2 -2
- data/app/views/camaleon_cms/admin/posts/_sidebar.html.erb +1 -1
- data/app/views/camaleon_cms/admin/posts/index.html.erb +3 -2
- data/app/views/camaleon_cms/admin/sessions/forgot.html.erb +2 -2
- data/app/views/camaleon_cms/admin/sessions/login.html.erb +3 -5
- data/app/views/camaleon_cms/admin/sessions/register.html.erb +1 -1
- data/app/views/camaleon_cms/admin/settings/_configuration_settings.html.erb +2 -2
- data/app/views/camaleon_cms/admin/settings/custom_fields/fields/_posts.html.erb +1 -1
- data/app/views/camaleon_cms/admin/user_roles/index.html.erb +8 -2
- data/app/views/camaleon_cms/admin/users/form.html.erb +2 -2
- data/app/views/camaleon_cms/admin/users/index.html.erb +8 -1
- data/app/views/layouts/camaleon_cms/admin.html.erb +2 -2
- data/config/initializers/active_record_extension.rb +9 -0
- data/config/initializers/assets.rb +1 -1
- data/config/locales/camaleon_cms/admin/en.yml +1 -1
- data/config/locales/camaleon_cms/admin/es.yml +2 -2
- data/config/locales/camaleon_cms/admin/fr.yml +1 -1
- data/config/locales/camaleon_cms/admin/it.yml +1 -1
- data/config/locales/camaleon_cms/admin/js.yml +40 -40
- data/config/locales/camaleon_cms/admin/nl.yml +1 -1
- data/config/locales/camaleon_cms/admin/pt-BR.yml +1 -1
- data/config/locales/camaleon_cms/admin/pt.yml +1 -1
- data/config/locales/camaleon_cms/admin/ru.yml +1 -1
- data/config/locales/camaleon_cms/admin/zh-CH.yml +56 -30
- data/config/routes/frontend.rb +53 -14
- data/lib/camaleon_cms/engine.rb +4 -2
- data/lib/camaleon_cms/version.rb +1 -1
- data/lib/ext/string.rb +10 -2
- data/lib/generators/camaleon_cms/gem_plugin_generator.rb +3 -2
- data/spec/dummy/db/schema.rb +11 -0
- data/spec/dummy/log/test.log +56824 -0
- data/spec/features/pages_spec.rb +2 -1
- data/spec/features/posts_spec.rb +3 -1
- data/spec/spec_helper.rb +2 -2
- data/spec/support/common.rb +2 -2
- metadata +6 -10
- data/app/assets/javascripts/camaleon_cms/admin/login.js.coffee +0 -7
- data/app/assets/javascripts/camaleon_cms/admin/login_manifest.js +0 -15
- data/app/assets/javascripts/camaleon_cms/gibberish-aes.js +0 -1017
- data/lib/ext/aes_crypt.rb +0 -246
- data/spec/dummy/db/test.sqlite3 +0 -0
data/lib/ext/aes_crypt.rb
DELETED
@@ -1,246 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'delegate'
|
3
|
-
require 'securerandom'
|
4
|
-
|
5
|
-
module Gibberish
|
6
|
-
class AES
|
7
|
-
# Returns the AES object
|
8
|
-
#
|
9
|
-
# @param [String] password
|
10
|
-
# @param [Hash] opts
|
11
|
-
# @option opts [Symbol] :mode ('gcm') the AES mode to use
|
12
|
-
# @option opts [Symbol] :ks (256) keystrength
|
13
|
-
# @option opts [Symbol] :iter (100_000) number of PBKDF2 iterations to run on the password
|
14
|
-
# @option opts [Symbol] :max_iter (100_000) maximum allow iterations, set to prevent DOS attack of someone setting a large 'iter' value in the ciphertext JSON
|
15
|
-
# @option opts [Symbol] :ts (64) length of the authentication data hash
|
16
|
-
def initialize(password, opts={})
|
17
|
-
@cipher = SJCL.new(password, opts)
|
18
|
-
end
|
19
|
-
|
20
|
-
# Returns the ciphertext in the form of a JSON string
|
21
|
-
#
|
22
|
-
# @param [String] data
|
23
|
-
# @param [String] authenticated_data (Won't be encrypted)
|
24
|
-
def encrypt(data, authenticated_data='')
|
25
|
-
@cipher.encrypt(data, authenticated_data)
|
26
|
-
end
|
27
|
-
|
28
|
-
# Returns a Plaintext object (essentially a String with an additional 'adata' attribute)
|
29
|
-
#
|
30
|
-
# @param [String] ciphertext
|
31
|
-
def decrypt(ciphertext)
|
32
|
-
@cipher.decrypt(ciphertext)
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
class AES::SJCL
|
38
|
-
class CipherOptionsError < ArgumentError; end
|
39
|
-
class DecryptionError < StandardError; end
|
40
|
-
class Plaintext < SimpleDelegator
|
41
|
-
attr_reader :adata
|
42
|
-
def initialize(str, adata)
|
43
|
-
@adata = adata;
|
44
|
-
super(str)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
MAX_ITER = 100_000
|
49
|
-
ALLOWED_MODES = ['ccm', 'gcm']
|
50
|
-
ALLOWED_KS = [128, 192, 256]
|
51
|
-
ALLOWED_TS = [64, 96, 128]
|
52
|
-
DEFAULTS = {
|
53
|
-
v:1, iter:100_000, ks:256, ts:96,
|
54
|
-
mode:"gcm", adata:"", cipher:"aes", max_iter: MAX_ITER
|
55
|
-
}
|
56
|
-
def initialize(password, opts={})
|
57
|
-
@password = password
|
58
|
-
@opts = DEFAULTS.merge(opts)
|
59
|
-
check_cipher_options(@opts)
|
60
|
-
end
|
61
|
-
|
62
|
-
def encrypt(plaintext, adata='')
|
63
|
-
salt = SecureRandom.random_bytes(8)
|
64
|
-
iv = SecureRandom.random_bytes(12)
|
65
|
-
key = OpenSSL::PKCS5.pbkdf2_hmac(@password, salt, @opts[:iter], @opts[:ks]/8, 'SHA256')
|
66
|
-
cipherMode = "#{@opts[:cipher]}-#{@opts[:ks]}-#{@opts[:mode]}"
|
67
|
-
c = OpenSSL::Cipher.new(cipherMode)
|
68
|
-
c.encrypt
|
69
|
-
c.key = key
|
70
|
-
c.iv = iv
|
71
|
-
c.auth_data = adata
|
72
|
-
ct = c.update(plaintext) + c.final
|
73
|
-
tag = c.auth_tag(@opts[:ts]/8);
|
74
|
-
ct = ct + tag
|
75
|
-
out = {
|
76
|
-
v: @opts[:v], adata: adata, ks: @opts[:ks], ct: Base64.strict_encode64(ct).encode('utf-8'), ts: tag.length * 8,
|
77
|
-
mode: @opts[:mode], cipher: 'aes', iter: @opts[:iter], iv: Base64.strict_encode64(iv),
|
78
|
-
salt: Base64.strict_encode64(salt)
|
79
|
-
}
|
80
|
-
out.to_json
|
81
|
-
end
|
82
|
-
|
83
|
-
def decrypt(h)
|
84
|
-
begin
|
85
|
-
h = JSON.parse(h, {:symbolize_names => true})
|
86
|
-
rescue
|
87
|
-
raise "Unable to parse JSON of crypted text"
|
88
|
-
end
|
89
|
-
check_cipher_options(h)
|
90
|
-
key = OpenSSL::PKCS5.pbkdf2_hmac(@password, Base64.decode64(h[:salt]), h[:iter], h[:ks]/8, 'SHA256')
|
91
|
-
iv = Base64.decode64(h[:iv])
|
92
|
-
ct = Base64.decode64(h[:ct])
|
93
|
-
tag = ct[ct.length-h[:ts]/8,ct.length]
|
94
|
-
ct = ct[0,ct.length-h[:ts]/8]
|
95
|
-
cipherMode = "#{h[:cipher]}-#{h[:ks]}-#{h[:mode]}"
|
96
|
-
begin
|
97
|
-
c = OpenSSL::Cipher.new(cipherMode)
|
98
|
-
rescue RuntimeError => e
|
99
|
-
raise "OpenSSL error when initializing: #{e.message}"
|
100
|
-
end
|
101
|
-
c.decrypt
|
102
|
-
c.key = key
|
103
|
-
c.iv = iv
|
104
|
-
c.auth_tag = tag;
|
105
|
-
c.auth_data = h[:adata] || ""
|
106
|
-
begin
|
107
|
-
out = c.update(ct) + c.final();
|
108
|
-
rescue OpenSSL::Cipher::CipherError => e
|
109
|
-
raise DecryptionError.new();
|
110
|
-
end
|
111
|
-
return Plaintext.new(out.force_encoding('utf-8'), h[:adata])
|
112
|
-
end
|
113
|
-
|
114
|
-
# Assume the worst
|
115
|
-
def check_cipher_options(c_opts)
|
116
|
-
if @opts[:max_iter] < c_opts[:iter]
|
117
|
-
# Prevent DOS attacks from high PBKDF iterations
|
118
|
-
# You an increase this by passing in opts[:max_iter]
|
119
|
-
raise CipherOptionsError.new("Iteration count of #{c_opts[:iter]} exceeds the maximum of #{@opts[:max_iter]}")
|
120
|
-
elsif !ALLOWED_MODES.include?(c_opts[:mode])
|
121
|
-
raise CipherOptionsError.new("Mode '#{c_opts[:mode]}' not supported")
|
122
|
-
elsif !ALLOWED_KS.include?(c_opts[:ks])
|
123
|
-
raise CipherOptionsError.new("Keystrength of #{c_opts[:ks]} not supported")
|
124
|
-
elsif !ALLOWED_TS.include?(c_opts[:ts])
|
125
|
-
raise CipherOptionsError.new("Tag length of #{c_opts[:ts]} not supported")
|
126
|
-
elsif c_opts[:iv] && Base64.decode64(c_opts[:iv]).length > 12
|
127
|
-
raise CipherOptionsError.new("Initialization vector's greater than 12 bytes are not supported in Ruby.")
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
class AES::CBC
|
133
|
-
|
134
|
-
BUFFER_SIZE = 4096
|
135
|
-
|
136
|
-
attr_reader :password, :size, :cipher
|
137
|
-
|
138
|
-
# Initialize with the password
|
139
|
-
#
|
140
|
-
# @param [String] password
|
141
|
-
# @param [Integer] size
|
142
|
-
# @param [String] mode
|
143
|
-
def initialize(password, size=256, mode="cbc")
|
144
|
-
@password = password
|
145
|
-
@size = size
|
146
|
-
@mode = mode
|
147
|
-
@cipher = OpenSSL::Cipher::Cipher.new("aes-#{size}-#{mode}")
|
148
|
-
end
|
149
|
-
|
150
|
-
def encrypt(data, opts={})
|
151
|
-
salt = generate_salt(opts[:salt])
|
152
|
-
setup_cipher(:encrypt, salt)
|
153
|
-
e = cipher.update(data) + cipher.final
|
154
|
-
e = "Salted__#{salt}#{e}" #OpenSSL compatible
|
155
|
-
opts[:binary] ? e : Base64.encode64(e)
|
156
|
-
end
|
157
|
-
alias :enc :encrypt
|
158
|
-
alias :e :encrypt
|
159
|
-
|
160
|
-
def decrypt(data, opts={})
|
161
|
-
raise ArgumentError, 'Data is too short' unless data.length >= 16
|
162
|
-
data = Base64.decode64(data) unless opts[:binary]
|
163
|
-
salt = data[8..15]
|
164
|
-
data = data[16..-1]
|
165
|
-
setup_cipher(:decrypt, salt)
|
166
|
-
cipher.update(data) + cipher.final
|
167
|
-
end
|
168
|
-
alias :dec :decrypt
|
169
|
-
alias :d :decrypt
|
170
|
-
|
171
|
-
def encrypt_file(from_file, to_file, opts={})
|
172
|
-
salt = generate_salt(opts[:salt])
|
173
|
-
setup_cipher(:encrypt, salt)
|
174
|
-
buf = ""
|
175
|
-
File.open(to_file, "wb") do |outf|
|
176
|
-
outf << "Salted__#{salt}"
|
177
|
-
File.open(from_file, "rb") do |inf|
|
178
|
-
while inf.read(4096, buf)
|
179
|
-
outf << self.cipher.update(buf)
|
180
|
-
end
|
181
|
-
outf << self.cipher.final
|
182
|
-
end
|
183
|
-
end
|
184
|
-
end
|
185
|
-
alias :enc_file :encrypt_file
|
186
|
-
alias :ef :encrypt_file
|
187
|
-
|
188
|
-
def decrypt_file(from_file, to_file)
|
189
|
-
buf = ""
|
190
|
-
salt = ""
|
191
|
-
File.open(to_file, "wb") do |outf|
|
192
|
-
File.open(from_file, "rb") do |inf|
|
193
|
-
inf.seek(8, IO::SEEK_SET)
|
194
|
-
inf.read(8, salt)
|
195
|
-
setup_cipher(:decrypt, salt)
|
196
|
-
while inf.read(4096, buf)
|
197
|
-
outf << self.cipher.update(buf)
|
198
|
-
end
|
199
|
-
outf << self.cipher.final
|
200
|
-
end
|
201
|
-
end
|
202
|
-
end
|
203
|
-
alias :dec_file :decrypt_file
|
204
|
-
alias :df :decrypt_file
|
205
|
-
|
206
|
-
def encrypt_stream(in_stream, out_stream, opts={})
|
207
|
-
salt = generate_salt(opts[:salt])
|
208
|
-
setup_cipher(:encrypt, salt)
|
209
|
-
out_stream << "Salted__#{salt}"
|
210
|
-
copy_stream in_stream, out_stream
|
211
|
-
end
|
212
|
-
|
213
|
-
def decrypt_stream(in_stream, out_stream)
|
214
|
-
header = in_stream.read(16)
|
215
|
-
salt = header[8..15]
|
216
|
-
setup_cipher(:decrypt, salt)
|
217
|
-
copy_stream in_stream, out_stream
|
218
|
-
end
|
219
|
-
|
220
|
-
private
|
221
|
-
|
222
|
-
def generate_salt(supplied_salt)
|
223
|
-
if supplied_salt
|
224
|
-
return supplied_salt.to_s[0,8].ljust(8,'.')
|
225
|
-
end
|
226
|
-
s = ''
|
227
|
-
8.times {s << rand(255).chr}
|
228
|
-
s
|
229
|
-
end
|
230
|
-
|
231
|
-
def setup_cipher(method, salt)
|
232
|
-
cipher.send(method)
|
233
|
-
cipher.pkcs5_keyivgen(password, salt, 1)
|
234
|
-
end
|
235
|
-
|
236
|
-
def copy_stream(in_stream, out_stream)
|
237
|
-
buf = ''
|
238
|
-
while in_stream.read(BUFFER_SIZE, buf)
|
239
|
-
out_stream << cipher.update(buf)
|
240
|
-
end
|
241
|
-
out_stream << cipher.final
|
242
|
-
out_stream.flush
|
243
|
-
end
|
244
|
-
|
245
|
-
end
|
246
|
-
end
|
data/spec/dummy/db/test.sqlite3
DELETED
Binary file
|