ree 1.2.4 → 1.2.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a73f9d4ffa414ae499d87732f896c437117f65b52b7675908eb8581d482946f4
4
- data.tar.gz: '0328c44c6cb7d7dddae52494fb057e1b88f84a8d2c7f28ea62c202bcb1c74125'
3
+ metadata.gz: c4b0c989272201bf193600af16a5d4010842b6d169c4cd97afc9af4bea38d4cd
4
+ data.tar.gz: 0723ffdd0c7fdfb7220348d7bad7d0af8691f66330c24d64ff9e4d52300802dc
5
5
  SHA512:
6
- metadata.gz: 367764b547db08f4c975a0ea141c7563e5536612d05bf48388cf8b9100dc381573dcdb9081b6c73a6880ff9bc57fbe45cbda09c51030aa370bd032997a372cd2
7
- data.tar.gz: 4177a967cc3fa694fc03b6302fc10de386dea9ec2c328d16fbe53f4a765c1b4e0d25e9817d99ea0100fca3975b470a73192bc848d77684235771524651e06657
6
+ metadata.gz: ca5e021ac6507f3679d44fd7fd48068f8918a5990fbd2b993f19e55db06cc1e80c42a23796a9962cdb29b1e20a2e979d7d7765030ca58997979fc7a8bf5cac1d
7
+ data.tar.gz: d12e9983fea63b43385e686072922b3f8f7bc5dc0e5864a276c3d80d7fcd31e9021ed6c8337814ada8c75cd76add04eab81a903df747833b0bcc69ea30a22e78
data/Gemfile.lock CHANGED
@@ -1,13 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ree (1.2.4)
4
+ ree (1.2.6)
5
+ base64
5
6
  commander (~> 5.0.0)
6
7
  logger (~> 1.6.5)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
10
11
  specs:
12
+ base64 (0.3.0)
11
13
  commander (5.0.0)
12
14
  highline (~> 3.0.0)
13
15
  debug (1.9.1)
data/exe/ree CHANGED
@@ -223,6 +223,87 @@ class ReeCliRunner
223
223
  end
224
224
  end
225
225
 
226
+ command :"licensing.register_client" do |c|
227
+ c.syntax = 'ree licensing.register_client --name=NAME --contact=CONTACT'
228
+ c.description = 'register a new licensing client'
229
+ c.summary = '> ' + c.description
230
+ c.example 'register a client', 'ree licensing.register_client --name="Glabix" --contact="hello@glabix.com" --metadata="type=enterprise,country=RU"'
231
+ c.option '--name NAME', String, 'Client name'
232
+ c.option '--contact CONTACT', String, 'Client contact email'
233
+ c.option '--metadata METADATA', String, 'Client metadata (key=value pairs separated by commas)'
234
+ c.option '--clients_dir DIR', String, 'Directory for clients.json (default: current dir)'
235
+ c.action do |args, options|
236
+ options_hash = options.__hash__
237
+ options_hash.delete(:trace)
238
+
239
+ raise Ree::Error.new("--name is required") unless options_hash[:name]
240
+ raise Ree::Error.new("--contact is required") unless options_hash[:contact]
241
+
242
+ Ree::CLI::Licensing::RegisterClient.run(
243
+ name: options_hash[:name],
244
+ contact: options_hash[:contact],
245
+ metadata_str: options_hash[:metadata],
246
+ clients_dir: options_hash[:clients_dir] || Dir.pwd
247
+ )
248
+ end
249
+ end
250
+
251
+ command :"licensing.obfuscate" do |c|
252
+ c.syntax = 'ree licensing.obfuscate --source_path=PATH --target_path=PATH --client_id=ID --expires_at=DATE'
253
+ c.description = 'obfuscate a Ree project for distribution'
254
+ c.summary = '> ' + c.description
255
+ c.example 'obfuscate project', 'ree licensing.obfuscate --source_path=./project --target_path=./dist --client_id=client_abc123 --expires_at="2026-12-31"'
256
+ c.option '--source_path PATH', String, 'Source project path'
257
+ c.option '--target_path PATH', String, 'Target distribution path'
258
+ c.option '--client_id ID', String, 'Client ID from clients.json'
259
+ c.option '--expires_at DATE', String, 'License expiration date (YYYY-MM-DD)'
260
+ c.option '--exclude_files FILES', String, 'Comma-separated list of files to exclude'
261
+ c.option '--clients_dir DIR', String, 'Directory for clients.json (default: current dir)'
262
+ c.action do |args, options|
263
+ options_hash = options.__hash__
264
+ options_hash.delete(:trace)
265
+
266
+ raise Ree::Error.new("--source_path is required") unless options_hash[:source_path]
267
+ raise Ree::Error.new("--target_path is required") unless options_hash[:target_path]
268
+ raise Ree::Error.new("--client_id is required") unless options_hash[:client_id]
269
+ raise Ree::Error.new("--expires_at is required") unless options_hash[:expires_at]
270
+
271
+ Ree::CLI::Licensing::Obfuscate.run(
272
+ source_path: options_hash[:source_path],
273
+ target_path: options_hash[:target_path],
274
+ client_id: options_hash[:client_id],
275
+ expires_at: options_hash[:expires_at],
276
+ exclude_files: options_hash[:exclude_files] || "",
277
+ clients_dir: options_hash[:clients_dir] || Dir.pwd
278
+ )
279
+ end
280
+ end
281
+
282
+ command :"licensing.renew_license" do |c|
283
+ c.syntax = 'ree licensing.renew_license --client_id=ID --expires_at=DATE'
284
+ c.description = 'renew a license for an existing client'
285
+ c.summary = '> ' + c.description
286
+ c.example 'renew license', 'ree licensing.renew_license --client_id=client_abc123 --expires_at="2028-01-01"'
287
+ c.option '--client_id ID', String, 'Client ID from clients.json'
288
+ c.option '--expires_at DATE', String, 'New license expiration date (YYYY-MM-DD)'
289
+ c.option '--output_path PATH', String, 'Output path for license.json'
290
+ c.option '--clients_dir DIR', String, 'Directory for clients.json (default: current dir)'
291
+ c.action do |args, options|
292
+ options_hash = options.__hash__
293
+ options_hash.delete(:trace)
294
+
295
+ raise Ree::Error.new("--client_id is required") unless options_hash[:client_id]
296
+ raise Ree::Error.new("--expires_at is required") unless options_hash[:expires_at]
297
+
298
+ Ree::CLI::Licensing::RenewLicense.run(
299
+ client_id: options_hash[:client_id],
300
+ expires_at: options_hash[:expires_at],
301
+ output_path: options_hash[:output_path],
302
+ clients_dir: options_hash[:clients_dir] || Dir.pwd
303
+ )
304
+ end
305
+ end
306
+
226
307
  command :"gen.index_project" do |c|
227
308
  c.syntax = 'ree gen.index_project'
228
309
  c.description = 'generate index schema of methods'
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ree
4
+ module CLI
5
+ module Licensing
6
+ class Obfuscate
7
+ class << self
8
+ def run(source_path:, target_path:, client_id:, expires_at:, exclude_files: "", clients_dir: Dir.pwd, stdout: $stdout)
9
+ exclude_list = exclude_files.to_s.split(',').map(&:strip).reject(&:empty?)
10
+
11
+ Ree::Licensing::Obfuscator.run(
12
+ source_path: source_path,
13
+ target_path: target_path,
14
+ client_id: client_id,
15
+ expires_at: expires_at,
16
+ clients_dir: clients_dir,
17
+ exclude_files: exclude_list,
18
+ stdout: stdout
19
+ )
20
+ rescue Ree::Error => e
21
+ stdout.puts "Error: #{e.message}"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ree
4
+ module CLI
5
+ module Licensing
6
+ class RegisterClient
7
+ class << self
8
+ def run(name:, contact:, metadata_str: nil, clients_dir: Dir.pwd, stdout: $stdout)
9
+ metadata = parse_metadata(metadata_str)
10
+
11
+ store = Ree::Licensing::ClientStore.new(clients_dir)
12
+ client = store.register_client(
13
+ name: name,
14
+ contact: contact,
15
+ metadata: metadata
16
+ )
17
+
18
+ stdout.puts "Client registered successfully:"
19
+ stdout.puts " Client ID: #{client['client_id']}"
20
+ stdout.puts " Name: #{client['name']}"
21
+ stdout.puts " Contact: #{client['contact']}"
22
+ stdout.puts " Saved to: #{File.join(clients_dir, 'clients.json')}"
23
+
24
+ client
25
+ rescue Ree::Error => e
26
+ stdout.puts "Error: #{e.message}"
27
+ end
28
+
29
+ private
30
+
31
+ def parse_metadata(metadata_str)
32
+ return {} if metadata_str.nil? || metadata_str.empty?
33
+
34
+ metadata_str.split(',').each_with_object({}) do |pair, hash|
35
+ key, value = pair.split('=', 2)
36
+ hash[key.strip] = value&.strip
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Ree
6
+ module CLI
7
+ module Licensing
8
+ class RenewLicense
9
+ class << self
10
+ def run(client_id:, expires_at:, output_path: nil, clients_dir: Dir.pwd, stdout: $stdout)
11
+ store = Ree::Licensing::ClientStore.new(clients_dir)
12
+ client = store.find_client(client_id)
13
+ raise Ree::Error.new("Client #{client_id} not found") unless client
14
+
15
+ last_license = store.last_license(client_id)
16
+ raise Ree::Error.new("No existing license found for #{client_id}") unless last_license
17
+
18
+ result = Ree::Licensing::LicenseGenerator.generate(
19
+ client_id: client_id,
20
+ private_key_pem: client['private_key_pem'],
21
+ public_key_pem: client['public_key_pem'],
22
+ aes_key_hex: last_license['aes_key_hex'],
23
+ iv_hex: last_license['iv_hex'],
24
+ expires_at: expires_at
25
+ )
26
+
27
+ store.add_license(client_id, result[:license_record])
28
+
29
+ output = output_path || File.join(clients_dir, "license_#{client_id}.json")
30
+ File.write(output, JSON.pretty_generate(result[:license_file]))
31
+
32
+ stdout.puts "License renewed successfully:"
33
+ stdout.puts " Client ID: #{client_id}"
34
+ stdout.puts " Expires at: #{expires_at}"
35
+ stdout.puts " License file: #{output}"
36
+
37
+ result
38
+ rescue Ree::Error => e
39
+ stdout.puts "Error: #{e.message}"
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
data/lib/ree/cli.rb CHANGED
@@ -8,5 +8,11 @@ module Ree
8
8
  autoload :GenerateTemplate, 'ree/cli/generate_template'
9
9
  autoload :Indexing, 'ree/cli/indexing'
10
10
  autoload :SpecRunner, 'ree/cli/spec_runner'
11
+
12
+ module Licensing
13
+ autoload :RegisterClient, 'ree/cli/licensing/register_client'
14
+ autoload :Obfuscate, 'ree/cli/licensing/obfuscate'
15
+ autoload :RenewLicense, 'ree/cli/licensing/renew_license'
16
+ end
11
17
  end
12
18
  end
@@ -95,7 +95,22 @@ class Ree::PackageLoader
95
95
 
96
96
  Ree.logger.debug("load_file(:#{package_name}, '#{path}')")
97
97
 
98
- Kernel.require(path)
98
+ if Ree.obfuscated?
99
+ load_encrypted_file(path)
100
+ else
101
+ Kernel.require(path)
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def load_encrypted_file(path)
108
+ license = Ree.license
109
+ full_path = path.end_with?('.rb') ? path : "#{path}.rb"
110
+ encrypted_data = File.binread(full_path)
111
+ bytecode = license.decrypt_file(encrypted_data)
112
+ iseq = RubyVM::InstructionSequence.load_from_binary(bytecode)
113
+ iseq.eval
99
114
  end
100
115
  end
101
116
 
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ree
4
+ module Licensing
5
+ class BytecodeCompiler
6
+ def self.compile_file(path)
7
+ iseq = RubyVM::InstructionSequence.compile_file(path)
8
+ iseq.to_binary
9
+ end
10
+
11
+ def self.compile_string(source, path = "(eval)")
12
+ iseq = RubyVM::InstructionSequence.compile(source, path)
13
+ iseq.to_binary
14
+ end
15
+
16
+ def self.load_from_binary(binary)
17
+ RubyVM::InstructionSequence.load_from_binary(binary)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'securerandom'
5
+ require 'openssl'
6
+
7
+ module Ree
8
+ module Licensing
9
+ class ClientStore
10
+ CLIENTS_FILE = 'clients.json'
11
+
12
+ def initialize(dir)
13
+ @dir = dir
14
+ @file_path = File.join(dir, CLIENTS_FILE)
15
+ end
16
+
17
+ def register_client(name:, contact:, metadata: {})
18
+ data = load_data
19
+ client_id = "client_#{SecureRandom.hex(8)}"
20
+ rsa_key = OpenSSL::PKey::RSA.new(4096)
21
+
22
+ client = {
23
+ 'client_id' => client_id,
24
+ 'name' => name,
25
+ 'contact' => contact,
26
+ 'metadata' => metadata,
27
+ 'created_at' => Date.today.to_s,
28
+ 'private_key_pem' => rsa_key.to_pem,
29
+ 'public_key_pem' => rsa_key.public_key.to_pem,
30
+ 'licenses' => []
31
+ }
32
+
33
+ data['clients'] << client
34
+ save_data(data)
35
+
36
+ client
37
+ end
38
+
39
+ def find_client(client_id)
40
+ data = load_data
41
+ data['clients'].detect { |c| c['client_id'] == client_id }
42
+ end
43
+
44
+ def add_license(client_id, license)
45
+ data = load_data
46
+ client = data['clients'].detect { |c| c['client_id'] == client_id }
47
+ raise Ree::Error.new("Client #{client_id} not found") unless client
48
+
49
+ client['licenses'] << license
50
+ save_data(data)
51
+ end
52
+
53
+ def last_license(client_id)
54
+ client = find_client(client_id)
55
+ raise Ree::Error.new("Client #{client_id} not found") unless client
56
+
57
+ client['licenses'].last
58
+ end
59
+
60
+ def load_data
61
+ if File.exist?(@file_path)
62
+ JSON.parse(File.read(@file_path))
63
+ else
64
+ { 'clients' => [] }
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def save_data(data)
71
+ File.write(@file_path, JSON.pretty_generate(data))
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'base64'
5
+ require 'openssl'
6
+ require 'date'
7
+
8
+ module Ree
9
+ module Licensing
10
+ class Decryptor
11
+ attr_reader :aes_key, :iv, :expires_at, :client_id
12
+
13
+ def initialize(aes_key:, iv:, expires_at:, client_id:)
14
+ @aes_key = aes_key
15
+ @iv = iv
16
+ @expires_at = expires_at
17
+ @client_id = client_id
18
+ end
19
+
20
+ def self.load_license(license_path)
21
+ unless File.exist?(license_path)
22
+ raise Ree::Error.new("License file not found: #{license_path}")
23
+ end
24
+
25
+ license_data = JSON.parse(File.read(license_path))
26
+ public_key_pem = license_data['public_key_pem']
27
+ encrypted_payload = Base64.strict_decode64(license_data['encrypted_payload'])
28
+
29
+ payload_json = Encryptor.rsa_public_decrypt(encrypted_payload, public_key_pem)
30
+ payload = JSON.parse(payload_json)
31
+
32
+ expires_at = Date.parse(payload['expires_at'])
33
+
34
+ if expires_at < Date.today
35
+ raise Ree::Error.new("License expired on #{payload['expires_at']}")
36
+ end
37
+
38
+ aes_key = [payload['aes_key_hex']].pack('H*')
39
+ iv = [payload['iv_hex']].pack('H*')
40
+
41
+ new(
42
+ aes_key: aes_key,
43
+ iv: iv,
44
+ expires_at: expires_at,
45
+ client_id: payload['client_id']
46
+ )
47
+ end
48
+
49
+ def decrypt_file(encrypted_data)
50
+ Encryptor.aes_decrypt(encrypted_data, @aes_key, @iv)
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+ require 'securerandom'
5
+ require 'json'
6
+ require 'base64'
7
+
8
+ module Ree
9
+ module Licensing
10
+ class Encryptor
11
+ def self.generate_aes_key
12
+ cipher = OpenSSL::Cipher::AES256.new(:CBC)
13
+ cipher.encrypt
14
+ {
15
+ key: cipher.random_key,
16
+ iv: cipher.random_iv
17
+ }
18
+ end
19
+
20
+ def self.aes_encrypt(data, key, iv)
21
+ cipher = OpenSSL::Cipher::AES256.new(:CBC)
22
+ cipher.encrypt
23
+ cipher.key = key
24
+ cipher.iv = iv
25
+ cipher.update(data) + cipher.final
26
+ end
27
+
28
+ def self.aes_decrypt(encrypted_data, key, iv)
29
+ cipher = OpenSSL::Cipher::AES256.new(:CBC)
30
+ cipher.decrypt
31
+ cipher.key = key
32
+ cipher.iv = iv
33
+ cipher.update(encrypted_data) + cipher.final
34
+ end
35
+
36
+ def self.rsa_private_encrypt(payload_json, private_key_pem)
37
+ rsa = OpenSSL::PKey::RSA.new(private_key_pem)
38
+ rsa.private_encrypt(payload_json)
39
+ end
40
+
41
+ def self.rsa_public_decrypt(encrypted_payload, public_key_pem)
42
+ rsa = OpenSSL::PKey::RSA.new(public_key_pem)
43
+ rsa.public_decrypt(encrypted_payload)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'base64'
5
+ require 'securerandom'
6
+
7
+ module Ree
8
+ module Licensing
9
+ class LicenseGenerator
10
+ def self.generate(client_id:, private_key_pem:, public_key_pem:, aes_key_hex:, iv_hex:, expires_at:)
11
+ payload = {
12
+ 'aes_key_hex' => aes_key_hex,
13
+ 'iv_hex' => iv_hex,
14
+ 'expires_at' => expires_at,
15
+ 'client_id' => client_id
16
+ }
17
+
18
+ payload_json = JSON.generate(payload)
19
+ encrypted_payload = Encryptor.rsa_private_encrypt(payload_json, private_key_pem)
20
+
21
+ license_file = {
22
+ 'version' => 1,
23
+ 'client_id' => client_id,
24
+ 'public_key_pem' => public_key_pem,
25
+ 'encrypted_payload' => Base64.strict_encode64(encrypted_payload)
26
+ }
27
+
28
+ license_record = {
29
+ 'license_id' => "lic_#{SecureRandom.hex(6)}",
30
+ 'expires_at' => expires_at,
31
+ 'aes_key_hex' => aes_key_hex,
32
+ 'iv_hex' => iv_hex,
33
+ 'created_at' => Date.today.to_s
34
+ }
35
+
36
+ { license_file: license_file, license_record: license_record }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,109 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'json'
5
+ require 'date'
6
+
7
+ module Ree
8
+ module Licensing
9
+ class Obfuscator
10
+ def self.run(source_path:, target_path:, client_id:, expires_at:, clients_dir:, exclude_files: [], stdout: $stdout)
11
+ new(
12
+ source_path: source_path,
13
+ target_path: target_path,
14
+ client_id: client_id,
15
+ expires_at: expires_at,
16
+ clients_dir: clients_dir,
17
+ exclude_files: exclude_files,
18
+ stdout: stdout
19
+ ).run
20
+ end
21
+
22
+ def initialize(source_path:, target_path:, client_id:, expires_at:, clients_dir:, exclude_files: [], stdout: $stdout)
23
+ @source_path = File.expand_path(source_path)
24
+ @target_path = File.expand_path(target_path)
25
+ @client_id = client_id
26
+ @expires_at = expires_at
27
+ @clients_dir = clients_dir
28
+ @exclude_files = exclude_files
29
+ @stdout = stdout
30
+ end
31
+
32
+ def run
33
+ start_time = Time.now
34
+
35
+ store = ClientStore.new(@clients_dir)
36
+ client = store.find_client(@client_id)
37
+ raise Ree::Error.new("Client #{@client_id} not found in clients.json") unless client
38
+
39
+ copy_project
40
+ remove_spec_dirs
41
+
42
+ aes_data = Encryptor.generate_aes_key
43
+ aes_key = aes_data[:key]
44
+ iv = aes_data[:iv]
45
+ aes_key_hex = aes_key.unpack1('H*')
46
+ iv_hex = iv.unpack1('H*')
47
+
48
+ encrypted_count = encrypt_ruby_files(aes_key, iv)
49
+
50
+ result = LicenseGenerator.generate(
51
+ client_id: @client_id,
52
+ private_key_pem: client['private_key_pem'],
53
+ public_key_pem: client['public_key_pem'],
54
+ aes_key_hex: aes_key_hex,
55
+ iv_hex: iv_hex,
56
+ expires_at: @expires_at
57
+ )
58
+
59
+ license_path = File.join(@target_path, 'license.json')
60
+ File.write(license_path, JSON.pretty_generate(result[:license_file]))
61
+
62
+ store.add_license(@client_id, result[:license_record])
63
+
64
+ elapsed = (Time.now - start_time).round(2)
65
+ @stdout.puts "Obfuscation complete:"
66
+ @stdout.puts " Files encrypted: #{encrypted_count}"
67
+ @stdout.puts " License file: #{license_path}"
68
+ @stdout.puts " Time: #{elapsed}s"
69
+
70
+ { encrypted_count: encrypted_count, license_path: license_path }
71
+ end
72
+
73
+ private
74
+
75
+ def copy_project
76
+ FileUtils.rm_rf(@target_path) if Dir.exist?(@target_path)
77
+ FileUtils.cp_r(@source_path, @target_path)
78
+ end
79
+
80
+ def remove_spec_dirs
81
+ Dir.glob(File.join(@target_path, '**/spec')).each do |spec_dir|
82
+ FileUtils.rm_rf(spec_dir) if File.directory?(spec_dir)
83
+ end
84
+ end
85
+
86
+ def encrypt_ruby_files(aes_key, iv)
87
+ count = 0
88
+ pattern = File.join(@target_path, '**/package/**/*.rb')
89
+
90
+ Dir.glob(pattern).each do |file_path|
91
+ basename = File.basename(file_path)
92
+ next if @exclude_files.include?(basename)
93
+
94
+ source = File.read(file_path)
95
+ if source.include?('require_relative')
96
+ raise Ree::Error.new("File contains require_relative: #{file_path}")
97
+ end
98
+
99
+ bytecode = BytecodeCompiler.compile_file(file_path)
100
+ encrypted = Encryptor.aes_encrypt(bytecode, aes_key, iv)
101
+ File.binwrite(file_path, encrypted)
102
+ count += 1
103
+ end
104
+
105
+ count
106
+ end
107
+ end
108
+ end
109
+ end
data/lib/ree/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ree
4
- VERSION = "1.2.4"
4
+ VERSION = "1.2.6"
5
5
  end
data/lib/ree.rb CHANGED
@@ -53,6 +53,15 @@ module Ree
53
53
  autoload :TemplateHandler, 'ree/handlers/template_handler'
54
54
  autoload :TemplateRenderer, 'ree/templates/template_renderer'
55
55
 
56
+ module Licensing
57
+ autoload :ClientStore, 'ree/licensing/client_store'
58
+ autoload :Encryptor, 'ree/licensing/encryptor'
59
+ autoload :Decryptor, 'ree/licensing/decryptor'
60
+ autoload :BytecodeCompiler, 'ree/licensing/bytecode_compiler'
61
+ autoload :LicenseGenerator, 'ree/licensing/license_generator'
62
+ autoload :Obfuscator, 'ree/licensing/obfuscator'
63
+ end
64
+
56
65
  PACKAGE = 'package'
57
66
  SCHEMAS = 'schemas'
58
67
  SCHEMA = 'schema'
@@ -124,6 +133,20 @@ module Ree
124
133
  !!@benchmark_mode
125
134
  end
126
135
 
136
+ def obfuscated?
137
+ ENV.has_key?('REE_LICENSE_KEY')
138
+ end
139
+
140
+ def license
141
+ @license ||= if obfuscated?
142
+ Ree::Licensing::Decryptor.load_license(ENV['REE_LICENSE_KEY'])
143
+ end
144
+ end
145
+
146
+ def reset_license
147
+ @license = nil
148
+ end
149
+
127
150
  def method_added_plugins
128
151
  @method_added_plugins ||= []
129
152
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ree
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.4
4
+ version: 1.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ruslan Gatiyatov
@@ -37,6 +37,20 @@ dependencies:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
39
  version: 1.6.5
40
+ - !ruby/object:Gem::Dependency
41
+ name: base64
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
40
54
  - !ruby/object:Gem::Dependency
41
55
  name: debug
42
56
  requirement: !ruby/object:Gem::Requirement
@@ -86,6 +100,9 @@ files:
86
100
  - lib/ree/cli/indexing/index_package.rb
87
101
  - lib/ree/cli/indexing/index_project.rb
88
102
  - lib/ree/cli/init.rb
103
+ - lib/ree/cli/licensing/obfuscate.rb
104
+ - lib/ree/cli/licensing/register_client.rb
105
+ - lib/ree/cli/licensing/renew_license.rb
89
106
  - lib/ree/cli/spec_runner.rb
90
107
  - lib/ree/container.rb
91
108
  - lib/ree/contracts.rb
@@ -166,6 +183,12 @@ files:
166
183
  - lib/ree/gen/package.rb
167
184
  - lib/ree/handlers/template_handler.rb
168
185
  - lib/ree/inspectable.rb
186
+ - lib/ree/licensing/bytecode_compiler.rb
187
+ - lib/ree/licensing/client_store.rb
188
+ - lib/ree/licensing/decryptor.rb
189
+ - lib/ree/licensing/encryptor.rb
190
+ - lib/ree/licensing/license_generator.rb
191
+ - lib/ree/licensing/obfuscator.rb
169
192
  - lib/ree/link_dsl.rb
170
193
  - lib/ree/method_added_hook.rb
171
194
  - lib/ree/object_compiler.rb