update license control

This commit is contained in:
Thein Lin Kyaw
2020-06-02 14:23:08 +06:30
parent 51932b8a86
commit da75403437
3 changed files with 244 additions and 153 deletions

View File

@@ -1,12 +1,15 @@
require 'yaml'
class License
include HTTParty
include ActionDispatch::Http
base_uri "connect.smartsales.asia/api"
base_uri "https://l.doemal.app//api"
attr_accessor :name, :address_1, :address_2, :township, :city, :country, :email, :phone, :fax, :logo, :subdomain,
:plan_activation_date, :plan_next_renewal_date, :plan_max_products,:plan_max_customers, :plan_active_connections,
:dbhost, :dbschema, :dbusername, :dbpassword, :exchange_unqiue_id, :localqueue_host,:server_mode,:localhost_address,
:localqueue_user, :localqueue_password, :remotequeue_host, :remotequeue_user, :remotequeue_password, :api_token, :app_token
:localqueue_user, :localqueue_password, :remotequeue_host, :remotequeue_user, :remotequeue_password, :api_token, :app_token, :lookup
@license = nil
@secret = nil
@@ -14,14 +17,17 @@ class License
def initialize(server = "", lookup = "")
#this code is hard-code to reflect server mode - Very important.
self.server_mode = ENV["SERVER_MODE"]
unless ENV["SERVER_MODE"] == "cloud"
self.server_mode = "application"
end
self.lookup = lookup
if (server != "")
self.class.base_uri server
end
end
# For Cloud
def detail_with_local_cache(lookup)
def detail_with_local_cache
aes = MyAesCrypt.new
aes_key, aes_iv = aes.export_to_file(lookup)
@@ -69,65 +75,75 @@ class License
end
# For Local System
def detail_with_local_file()
renewal_date_str = read_license("renewable_date")
if check_expiring(renewal_date_str)
# return for all ok
return 1
def detail_with_local_file
if expired?
return 0
elsif expire_in(30)?
return 2
else
has_license = verify_license()
if has_license
# return for expiring
return 2
else
return 0
end
return 1
end
# end
end
# License Activation
def license_activate (shop, license_key, db_host, db_schema, db_user, db_password)
aes = MyAesCrypt.new
aes_key, aes_iv = aes.export_key(license_key)
@params = { query: { lookup_type: self.server_mode, iv_key: aes_iv, license_key: license_key } }
response = self.class.get("/activate", @params)
@activate = response.parsed_response
if (@activate["status"])
##Check from local redis - if available load local otherwise get from remote
cache_key = "shop:#{@activate["shop_name"]}"
begin
response = self.class.get("/activate", @params)
@activate = response.parsed_response
cache_license = nil
if (@activate["status"])
##Get redis connection from connection pool
redis = Redis.new
cache_license = redis.get(cache_key)
##Check from local redis - if available load local otherwise get from remote
cache_key = "shop:#{@activate["shop_name"]}"
Rails.logger.info "Cache key - " + cache_key.to_s
##Get redis connection from connection pool
# redis = Redis.new
# cache_license = redis.get(cache_key)
if cache_license.nil?
Rails.logger.info "Cache key - " + cache_key.to_s
# if cache_license.nil?
cache = {"shop" => @activate["shop_name"], "key" => aes_key, "iv" => @activate["iv_key"], "renewable_date" => @activate["renewable_date"] }
redis = Redis.new
redis.set(cache_key, Marshal.dump(cache))
end
# end
Rails.logger.info "License - " + response.parsed_response.to_s
Rails.logger.info "License - " + response.parsed_response.to_s
response = create_license_file(@activate)
if(response[:status])
#sym_path = "/home/user/symmetric/"
sym_path = File.expand_path("~/symmetric/")
response = create_symmetric_config(sym_path, db_host, db_schema, db_user, db_password)
response = create_license_file(@activate)
if(response[:status])
response = run_symmetric(sym_path)
#sym_path = "/home/user/symmetric/"
sym_path = File.expand_path("~/symmetric/")
response = create_symmetric_config(sym_path, db_host, db_schema, db_user, db_password)
if(response[:status])
response = run_symmetric(sym_path)
end
end
else
response = { "status": false, "message": "Activation Failed! Please contact code2lab call center!"}
end
else
response = { "status": false, "message": "Activation Failed! Please contact code2lab call center!"}
rescue SocketError => e
Rails.logger.debug "In SocketError No Internet connection !"
response = { "status": false, "message": "In SocketError No Internet connection !"}
rescue HTTParty::Error
Rails.logger.debug "Server Error HTTParty"
response = { "status": false, "message": "Server Error HTTParty"}
rescue Net::OpenTimeout
Rails.logger.debug "connection Timeout"
response = { "status": false, "message": "Connection Timeout"}
rescue OpenURI::HTTPError
Rails.logger.debug "Can't connect server"
response = { "status": false, "message": "Can't connect server"}
end
return response
end
@@ -137,16 +153,16 @@ class License
@params = { query: {lookup_type: "application", api_token: api_token} }
begin
response = self.class.get("/verify", @params)
@varified = response.parsed_response
Rails.logger.debug "License Remote Response - " + response.parsed_response.to_s
if (@varified["status"])
if (!check_expired(@varified["renewable_date"]))
return true
end
else
delete_license_file
response = self.class.get("/verify", @params)
@varified = response.parsed_response
Rails.logger.debug "License Remote Response - " + response.parsed_response.to_s
if (@varified["status"])
if (!check_expired(@varified["renewable_date"]))
return true
end
else
delete_license_file
end
rescue SocketError => e
Rails.logger.debug "In SocketError No Internet connection ! "
@@ -164,12 +180,23 @@ class License
return false
end
# Check Expired before 30 days
def check_expiring(renewal_date_str)
if !renewal_date_str.empty?
def expired?
if renewal_date_str = read_license("renewable_date")
renewal_date = DateTime.parse(renewal_date_str)
renewal_date > Date.today.advance(:days => 30)
renewal_date < Date.today
end
end
def expire_in?(days)
if renewal_date_str = read_license("renewable_date")
renewal_date = DateTime.parse(renewal_date_str)
renewal_date < days.days.from_now
end
end
def days_to_expire
if renewal_date_str = read_license("renewable_date")
Date.today - DateTime.parse(renewal_date_str).to_date
end
end
@@ -188,39 +215,59 @@ class License
end
end
def check_license_subdomain
aes = MyAesCrypt.new
aes_key, aes_iv = aes.export_key(lookup)
params = { query: { lookup_type: "cloud", lookup: lookup, iv_key: aes_iv} }
response = self.class.get("/subdomain", params)
response.parsed_response["status"]
end
# Check License File exists
def self.check_license_file
return File.exist?("config/license.yml")
def self.check_license_file(lookup)
return unless File.exist?("config/license.yml")
if license = YAML.load_file("config/license.yml")
if license[lookup].nil?
if ENV["SERVER_MODE"] == "application"
license[lookup] = license.values.first
else
tld_length = Rails.application.config.action_dispatch.tld_length
subdomains = URL.extract_subdomains(lookup, tld_length)
if key = license.keys.find { |k| URL.extract_subdomains(k, tld_length).last == subdomains.last}
license[lookup] = license[key]
end
end
if license[lookup]
File.open("config/license.yml", "w") { |file| file.write license.to_yaml }
end
end
return license[lookup]
end
end
# read line by key for license file
def read_license(key_name)
decrypted_line = ""
key, iv = get_redis_key()
if File.exist?("config/license.yml")
File.open("config/license.yml").each do |line|
if line.include? (key_name)
decrypted_line_array = line.split(": ")
decrypted_line = AESCrypt.decrypt_data(decode_str(decrypted_line_array[1]), decode_str(key), decode_str(iv), ENV['CIPHER_TYPE'])
if license = YAML.load(File.read("config/license.yml"))
if license[lookup]
AESCrypt.decrypt_data(decode_str(license[lookup][key_name]), decode_str(key), decode_str(iv), ENV['CIPHER_TYPE'])
end
end
end
return decrypted_line
end
# read line by key for license file without decrypt
def read_license_no_decrypt(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 = decrypted_line_array[1]
if license = YAML.load_file("config/license.yml")
if license[lookup]
decrypted_line = license[lookup][key]
end
end
end
return decrypted_line
end
# Update license file for line
@@ -231,18 +278,13 @@ class License
crypted_str = AESCrypt.encrypt_data(new_content, decode_str(key), decode_str(iv), ENV['CIPHER_TYPE'])
end
content_str = read_license_no_decrypt(content)
if File.exist?("config/license.yml")
file_str = File.read("config/license.yml")
new_file_str = file_str.gsub(content_str, encode_str(crypted_str))
if license = YAML.load_file("config/license.yml")
license[lookup][content] = encode_str(crypted_str)
# To write changes to the file, use:
File.open("config/license.yml", "w") {|file| file.puts new_file_str }
# File.open("config/license.yml").each do |line|
# new_file_str = line.gsub(content, crypted_str)
# f.put
# end
# To write changes to the file, use:
File.open("config/license.yml", "w") {|file| file.write(license.to_yaml) }
end
end
end
@@ -284,12 +326,11 @@ class License
##Check from local redis - if available load local otherwise get from remote
cache_key = "shop:#{shop.chomp}"
cache_shop = nil
##Get redis connection from connection pool
redis = Redis.new
cache_shop = redis.get(cache_key)
puts Marshal.load(cache_shop)
if !cache_shop.nil?
@shop = Marshal.load(cache_shop)
key = @shop["key"]
@@ -308,29 +349,38 @@ class License
# License File Creation
def create_license_file(response_data)
if File.exist?("config/license.yml")
delete_license_file
end
begin
# Licese File Creation
File.open("config/license.yml", "w") do |f|
f.puts("iv_key: #{response_data['iv_key']}")
f.puts("shop_name: #{response_data['shop_name']}")
f.puts("email: #{response_data['email']}")
f.puts("telephone: #{response_data['telephone']}")
f.puts("fax: #{response_data['fax']}")
f.puts("address: #{response_data['address']}")
f.puts("dbhost: #{response_data['dbhost']}")
f.puts("dbschema: #{response_data['dbschema']}")
f.puts("dbusername: #{response_data['dbusername']}")
f.puts("dbpassword: #{response_data['dbpassword']}")
f.puts("api_token: #{response_data['api_token']}")
f.puts("app_token: #{response_data['app_token']}")
f.puts("plan_sku: #{response_data['plan_sku']}")
f.puts("renewable_date: #{response_data['renewable_date']}")
f.puts("plan_name: #{response_data['plan_name']}")
config = { "iv_key" => response_data['iv_key'],
"shop_name" => response_data['shop_name'],
"email" => response_data['email'],
"telephone" => response_data['telephone'],
"fax" => response_data['fax'],
"address" => response_data['address'],
"dbhost" => response_data['dbhost'],
"dbschema" => response_data['dbschema'],
"dbusername" => response_data['dbusername'],
"dbpassword" => response_data['dbpassword'],
"api_token" => response_data['api_token'],
"app_token" => response_data['app_token'],
"plan_sku" => response_data['plan_sku'],
"renewable_date" => response_data['renewable_date'],
"plan_name" => response_data['plan_name'] }
if File.exist?("config/license.yml")
license = YAML.load_file("config/license.yml")
end
if license
license.each do |k,v|
license[k] = config if v["shop_name"] == config["shop_name"]
end
license[lookup] = config
end
license ||= {lookup => config}
File.open("config/license.yml", "w"){ |file| file.write(license.to_yaml) }
rescue IOError
response = { "status": false, "message": "Activation is success but something is wrong. \n Please contact code2lab call center!"}
end
@@ -387,10 +437,10 @@ class License
# f.write("initial.load.use.extract.job.enabled=true\n")
f.close
rescue IOError
response = { "status": false, "message": "Activation is success but something is wrong. \n Please contact code2lab call center!"}
return { "status": false, "message": "Activation is success but something is wrong. \n Please contact code2lab call center!"}
end
response = { "status": true, "message": "Success Activation. License also created."}
end
{ "status": true, "message": "Success Activation. License also created." }
end
# Run Symmetric