diff --git a/Gemfile.lock b/Gemfile.lock index f56a2d36..4cdc2ded 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -96,7 +96,6 @@ GEM concurrent-ruby (1.1.5) connection_pool (2.2.2) crass (1.0.5) - cups (0.0.7) database_cleaner (1.7.0) diff-lcs (1.3) erubi (1.9.0) @@ -335,7 +334,6 @@ DEPENDENCIES carrierwave (~> 1.0) chartkick coffee-rails (~> 4.2) - cups (~> 0.0.7) database_cleaner factory_girl_rails (~> 4.0) faker diff --git a/app/assets/stylesheets/BSBMaterial/style.css b/app/assets/stylesheets/BSBMaterial/style.css index a4620cf5..004439e9 100755 --- a/app/assets/stylesheets/BSBMaterial/style.css +++ b/app/assets/stylesheets/BSBMaterial/style.css @@ -11,7 +11,7 @@ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); border: none; position: fixed; - top: 0; + /*top: 0;*/ left: 0; z-index: 12; width: 100%; } @@ -6649,7 +6649,7 @@ fieldset[disabled] .form-control { box-shadow: 0 1px 5px rgba(0, 0, 0, 0.3); border: none; position: fixed; - top: 0; + /*top: 0;*/ left: 0; z-index: 12; width: 100%; } diff --git a/app/controllers/install_controller.rb b/app/controllers/install_controller.rb index 1ff003db..594c99ea 100755 --- a/app/controllers/install_controller.rb +++ b/app/controllers/install_controller.rb @@ -1,7 +1,6 @@ class InstallController < BaseController - skip_before_action :lookup_domain + # skip_before_action :set_current_tenant_by_subdomain_or_name skip_before_action :verify_authenticity_token - # before_action :check_license def index end @@ -9,7 +8,7 @@ class InstallController < BaseController def activate flag = "<%= ENV['AES_IV'] %>" key_base = "<%= ENV['secret_key_base'] %>" - + restaurant = params[:restaurant_name] license_key = params[:license_key] # admin_user = params[:admin_user] @@ -18,20 +17,20 @@ class InstallController < BaseController db_schema = params[:db_schema] db_user = params[:db_user] db_password = params[:db_password] - phrase = license_key - + phrase = license_key + # Check Exists IV # if flag == "<%= ENV['AES_IV'] %>" - # # Export for Key - # aes = MyAesCrypt.new + # # Export for Key + # aes = MyAesCrypt.new # aes_key, aes_iv = aes.export_key(phrase) - # else + # else # aes_key = ENV["AES_KEY"] # aes_iv = ENV["AES_IV"] # end - @license = License.new(ENV["SX_PROVISION_URL"]) - response = @license.license_activate(restaurant, license_key, db_host, db_schema, db_user, db_password) + @license = License.new(ENV["SX_PROVISION_URL"], request.host) + response = @license.license_activate(restaurant, license_key, db_host, db_schema, db_user, db_password) if response[:status] redirect_to root_url, notice: response["message"] else @@ -39,28 +38,24 @@ class InstallController < BaseController end end - def check_license - if License.check_license_file - redirect_to root_url + def lookup_domain + if ENV["SERVER_MODE"] == "cloud" + not_found + elsif ENV["SERVER_MODE"] == "application" + if check_license #(request.host) + redirect_to root_url + end + elsif request.subdomains.last && request.subdomains.last != "www" + if check_license #(request.host) + redirect_to root_url + elsif !check_subdomain(request.host) + not_found + end + else + not_found end end - # def lookup_domain - # if request.subdomain.present? && request.subdomain != "www" - # @license = current_license(ENV["SX_PROVISION_URL"], request.subdomain.downcase) - # if (!@license.nil?) - # # logger.info "Location - " + @license.name - # ActiveRecord::Base.establish_connection(website_connection(@license)) - # # logger.info "Connecting to - " + @license.subdomain + " - "+ @license.dbhost + "@" + @license.dbschema - # else - # # reconnect_default_db - # logger.info 'License is nil' - # # redirect_to root_url(:host => request.domain) + "store_error" - # render :json => [{ status: false, message: 'Invalid Access!'}] - # end - # end - # end - # def current_license(url, key) # @license = License.new(url, key) diff --git a/app/controllers/renew_license_controller.rb b/app/controllers/renew_license_controller.rb new file mode 100644 index 00000000..7ef245fe --- /dev/null +++ b/app/controllers/renew_license_controller.rb @@ -0,0 +1,17 @@ +class RenewLicenseController < ApplicationController + + def expire + @license = current_license + @plan = @license.read_license("plan_name") + @bis_name = @license.read_license_no_decrypt("shop_name") + @expired_at = @license.read_license("renewable_date") + @license_status = @license.detail_with_local_file + end + + def renew + status, message = current_license.verify_license + + redirect_to expire_url(message: message, status: status) + end + +end \ No newline at end of file diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 16e44953..93664fef 100755 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -5,8 +5,8 @@ module ApplicationHelper case level when :notice then "alert alert-info fade-in" when :success then "alert alert-success fade-in" - when :error then "alert alert-error fade-in" - when :alert then "alert alert-error fade-in" + when :error then "alert alert-warning fade-in" + when :alert then "alert alert-danger fade-in" end end diff --git a/app/models/license.rb b/app/models/license.rb index 2c550a1e..92781a22 100755 --- a/app/models/license.rb +++ b/app/models/license.rb @@ -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?(10) + 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 @@ -135,18 +151,26 @@ class License def verify_license api_token = read_license_no_decrypt("api_token") @params = { query: {lookup_type: "application", api_token: api_token} } + old_renewable_date = read_license("renewable_date") 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 old_renewable_date.to_date == @varified['renewable_date'].to_date + message = "*** License can't be verified. ***" + status = 2 + elsif old_renewable_date.to_date < @varified['renewable_date'].to_date + update_license("renewable_date", @varified['renewable_date']) + status = 1 + message = "*** License con be verified. ***" end + return status, message + + else + delete_license_file + end rescue SocketError => e Rails.logger.debug "In SocketError No Internet connection ! " @@ -164,12 +188,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 +223,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 +286,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,8 +334,6 @@ 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) @@ -308,29 +356,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 +444,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 diff --git a/app/views/home/dashboard.html.erb b/app/views/home/dashboard.html.erb index 6cd52f4e..b7bd5c44 100755 --- a/app/views/home/dashboard.html.erb +++ b/app/views/home/dashboard.html.erb @@ -189,7 +189,7 @@
Please wait...
+ <%= render 'shared/license_expire_warning' %> @@ -59,7 +60,7 @@ <% end %> <% end %> - <% end %> + <% end %> <%= yield %> + <%= render 'shared/license_expire_warning' %> <%= render 'layouts/header' %><%= @filter %>
+ <% end %>
+ <% if params[:message].present?
+ if params[:status].to_i == 1
+ color = 'text-success'
+ else
+ color = 'text-danger'
+ end
+ %>
+ <%= params[:message] %>