From 93769bacb73c906aed70abcfc2972cbdab4e4356 Mon Sep 17 00:00:00 2001 From: Yan Date: Tue, 14 Nov 2017 18:35:14 +0630 Subject: [PATCH] licensing --- app/controllers/application_controller.rb | 34 +++++----- app/models/AESEncDec.rb | 37 ----------- app/models/license.rb | 79 ++++++++++++++++++++--- config/secrets.yml | 7 +- 4 files changed, 92 insertions(+), 65 deletions(-) delete mode 100644 app/models/AESEncDec.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ea71f60e..ef56c79d 100755 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -4,7 +4,7 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception # lookup domain for db from provision - before_action :check_license, :lookup_domain, :set_locale + before_action :lookup_domain, :set_locale helper_method :current_company,:current_login_employee,:current_user # alias_method :current_user, :current_login_employee,:current_user @@ -24,7 +24,7 @@ class ApplicationController < ActionController::Base def lookup_domain if request.subdomain.present? && request.subdomain != "www" - @license = current_license(ENV["SX_PROVISION_URL"], request.subdomain.downcase) # request.subdomain.downcase + @license = cache_license(ENV["SX_PROVISION_URL"], request.subdomain.downcase) # request.subdomain.downcase if (!@license.nil?) # logger.info "Location - " + @license.name ActiveRecord::Base.establish_connection(website_connection(@license)) @@ -35,30 +35,32 @@ class ApplicationController < ActionController::Base # redirect_to root_url(:host => request.domain) + "store_error" render :json => [{ status: false, message: 'Invalid Access!'}] end + else + # check for license file + if check_license + current_license(ENV["SX_PROVISION_URL"]) + end end end - def cache_license() - @license = License.new(url, subdomain) - ##creating md5 hash - md5_hostname = Digest::MD5.new - md5key = md5_hostname.update(request.host) + def current_license(url) + @license = License.new(url) - if (@license.detail_with_local_cache(subdomain, md5key.to_s) == true) + if (@license.detail_with_local_file(lookup) == true) return @license else return nil end end - def current_license(url, key) - @license = License.new(url, key) + def cache_license(url, lookup) + @license = License.new(url, lookup) - # Export for Key - passphrase = key + ENV["secret_key_base"] - key, iv = AESEncDec.export_key(passphrase) + # Export for Key + aes = AesCrypt.new + aes_key, aes_iv = aes.export_key(lookup) - if (@license.detail_with_local_file(key, key, iv) == true) + if (@license.detail_with_local_cache(lookup, aes_key, aes_iv) == true) return @license else return nil @@ -107,9 +109,7 @@ class ApplicationController < ActionController::Base private def check_license if License.check_license_file - # if !License.check_license_valid - # redirect_to install_path - # end + return true else redirect_to install_path end diff --git a/app/models/AESEncDec.rb b/app/models/AESEncDec.rb deleted file mode 100644 index b70328ed..00000000 --- a/app/models/AESEncDec.rb +++ /dev/null @@ -1,37 +0,0 @@ -require 'openssl' -require 'base64' -require 'uri' - -class AESEncDec { - cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc") - -<<<<<<< HEAD - def self.export_key(passphrase) - # We want a 256 bit key symetric key based on passphrase - digest = Digest::SHA256.new - key = digest.update(passphrase) - # key = digest.digest - ENV['aes_key'] = cipher.key = key # stores the key in key, and also sets the generated key on the cipher - ENV['aes_iv'] = cipher.iv = cipher.random_iv # stores the iv in iv, and also sets the generated iv on the cipher - return cipher.key, cipher.iv - end - - def self.encrypt(data) - cipher.encrypt - cipher.key = ENV["aes_key"] - cipher.iv = ENV["aes_iv"] - encrypted = cipher.update(data) + cipher.final - encrypted = Base64.urlsafe_encode64(encrypted) - return encrypted - end - - def self.decrypt(data) - cipher.decrypt - cipher.key = ENV["aes_key"] - cipher.iv = ENV["aes_iv"] - - # Start the decryption - decoded = Base64.urlsafe_decode64(data) - decrypted = cipher.update(decoded) + cipher.final - end -} \ No newline at end of file diff --git a/app/models/license.rb b/app/models/license.rb index 9473f6a4..837a77f8 100755 --- a/app/models/license.rb +++ b/app/models/license.rb @@ -19,11 +19,8 @@ class License self.class.base_uri server end - # generate key for license file encrypt - # AESEncDec.export_key() - # @secret = ENV["aes_key"] - @params = { query: { device: "SX", token: SECRETS_CONFIG['provision_key'] } } + # @params = { query: { device: "SX", token: SECRETS_CONFIG['provision_key'] } } end def shop_code @@ -34,14 +31,52 @@ class License end end - def detail_with_local_cache(lookup) + def detail_with_local_cache(lookup, key, iv) ##Check from local redis - if available load local otherwise get from remote - cache_key = "store:license:#{@secret}:hostname" + cache_key = "#{lookup}:license:#{key}:hostname" + + # No Needs for current + # @secret = key + + cache_license = nil + + ##Get redis connection from connection pool + Redis.current do |conn| + cache_license = conn.get(cache_key) + end + + Rails.logger.info "Cache key - " + cache_key.to_s + if cache_license.nil? + ##change the d/e key + # @options = { query: {device: "SXlite", lookup: lookup, skey: @secret, token: SECRETS_CONFIG['provision_key']} } + @params = { query: { lookup_type: self.server_mode, lookup: lookup, encrypted_key: key, iv_key: iv} } + + response = self.class.get("/subdomain", @params) + @license = response.parsed_response + + if (@license["status"] == true) + + assign() + + Rails.logger.info "License - " + response.parsed_response.to_s + + Redis.current do |conn| + ##Remote - store the remote response in local redis cache + conn.set(cache_key, Marshal.dump(@license)) + ##ADD to List to remove later + conn.sadd("License:cache:keys", cache_key) + end + + return true + end + + Rails.logger.info 'API License' + end end - def detail_with_local_file(lookup, key, iv) - has_license = check_license_file + def detail_with_local_file(lookup) + has_license = verify_license() if has_license @@ -73,7 +108,6 @@ class License Rails.logger.info 'API License' else - @license = Marshal.load(cache_license) if cache_license Rails.logger.info 'Cache License' @@ -102,6 +136,20 @@ class License return false end + def verify_license + api_token = read_license("api_token") + @options = { query: {lookup_type: "application", token: api_token} } + response = self.class.get("/verify", @options) + @varified = response.parsed_response + + Rails.logger.debug "License Remote Response - " + response.parsed_response.to_s + if (@varified["status"]) + check_expire_date + else + delete_license_file + end + end + def check_remote_license(license_key) # @options = { query: {device: "cloud", key: license_key, skey: @secret, token: Rails.application.secrets.provision_key} } @options = { query: {lookup_type: "application", encrypted_key: @secret, token: SECRETS_CONFIG['provision_key']} } @@ -146,6 +194,19 @@ class License return File.exist?("config/license.yml") end + # read line by key for license file + def read_license(key) + decrypted_line = "" + if File.exist?("config/license.yml") + File.open("config/license.yml").each do |line| + if line.include? (key) + decrypted_line_array = line.split(":") + decrypted_line = AESEncDec.decrypt(decrypted_line_array[1]) + end + end + end + end + def assign # self.name = @license["name"] # self.address_1 = @license["address_1"] diff --git a/config/secrets.yml b/config/secrets.yml index 6dabc7c7..8f56c424 100755 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -12,7 +12,9 @@ development: secret_key_base: b61d85f8ed2a1a9e0eeece3443b3e8f838d002cc1d9f32115d8e93db920e2957adfedc57501d44741211538f3108b742cdeada87d5bfae796c53da1f90a3cd61 - sx_provision_url: 192.168.1.94:3002/api #provision.zsai.ws + sx_provision_url: provision.zsai.ws/api #192.168.1.94:3002 + server_mode: cloud + cipher_type: AES-256-CBC aes_key: <%= ENV['aes_key'] %> aes_iv: <%= ENV['aes_iv'] %> @@ -23,7 +25,8 @@ test: # instead read values from the environment. production: secret_key_base: c4bc81065013f9a3506d385bcbd49586c42e586488144b0de90c7da36867de9fa880f46b5c4f86f0ce9b7c783bb5a73bdb0e5605a47716567294390e726d3e22 - sx_provision_url: 192.168.1.94:3002/api #provision.zsai.ws + sx_provision_url: provision.zsai.ws/api #192.168.1.94:3002 + server_mode: cloud aes_key: <%= ENV['aes_key'] %> aes_iv: <%= ENV['aes_iv'] %>