diff --git a/controllers/custom_wizard/admin/pro.rb b/controllers/custom_wizard/admin/pro.rb index b0686af2..9f32045e 100644 --- a/controllers/custom_wizard/admin/pro.rb +++ b/controllers/custom_wizard/admin/pro.rb @@ -10,15 +10,15 @@ class CustomWizard::AdminProController < CustomWizard::AdminController def authorize request_id = SecureRandom.hex(32) cookies[:user_api_request_id] = request_id - redirect_to CustomWizard::ProAuthentication.generate_request(current_user.id, request_id).to_s + redirect_to CustomWizard::Pro.auth_request(current_user.id, request_id).to_s end def authorize_callback payload = params[:payload] request_id = cookies[:user_api_request_id] - CustomWizard::ProAuthentication.handle_response(request_id, payload) - CustomWizard::ProSubscription.update + CustomWizard::Pro.auth_response(request_id, payload) + CustomWizard::Pro.update_subscription redirect_to '/admin/wizards/pro' end @@ -32,7 +32,7 @@ class CustomWizard::AdminProController < CustomWizard::AdminController end def update_subscription - if CustomWizard::ProSubscription.update + if CustomWizard::Pro.update render json: success_json.merge( subscription: CustomWizard::ProSubscriptionSerializer.new( CustomWizard::ProSubscription.new, diff --git a/jobs/scheduled/update_pro_status.rb b/jobs/scheduled/update_pro_status.rb index 5f76f52b..6f947304 100644 --- a/jobs/scheduled/update_pro_status.rb +++ b/jobs/scheduled/update_pro_status.rb @@ -4,6 +4,6 @@ class CustomWizard::UpdateProSubscription < ::Jobs::Scheduled every 10.minutes def execute(args) - CustomWizard::ProSubscription.update + CustomWizard::Pro.update_subscription end end \ No newline at end of file diff --git a/lib/custom_wizard/pro.rb b/lib/custom_wizard/pro.rb index e6bf2b0b..f54dd92d 100644 --- a/lib/custom_wizard/pro.rb +++ b/lib/custom_wizard/pro.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class CustomWizard::Pro - NAMESPACE ||= "#{CustomWizard::PLUGIN_NAME}_pro" - attr_reader :authentication, :subscription @@ -11,6 +9,18 @@ class CustomWizard::Pro @subscription = CustomWizard::ProSubscription.new end + def server + "test.thepavilion.io" + end + + def subscription_type + "stripe" + end + + def client_name + "custom-wizard" + end + def authorized? @authentication.active? end @@ -19,7 +29,78 @@ class CustomWizard::Pro @subscription.active? end + def update_subscription + if @authentication.active? + response = Excon.get( + "https://#{server}/subscription-server/user-subscriptions/#{subscription_type}/#{client_name}", + headers: { + "User-Api-Key" => @authentication.api_key + } + ) + + if response.status == 200 + begin + data = JSON.parse(response.body).deep_symbolize_keys + rescue JSON::ParserError + return false + end + + return @subscription.update(data) + end + end + + @subscription.destroy + false + end + + def destroy + @authentication.destroy + end + + def auth_request(user_id, request_id) + keys = @authentication.generate_keys(user_id, request_id) + + params = { + public_key: keys.public_key, + nonce: keys.nonce, + client_id: @authentication.client_id, + auth_redirect: "#{Discourse.base_url}/admin/wizards/pro/authorize/callback", + application_name: SiteSetting.title, + scopes: "discourse-subscription-server:user_subscription" + } + + uri = URI.parse("https://#{server}/user-api-key/new") + uri.query = URI.encode_www_form(params) + uri.to_s + end + + def auth_response(request_id, payload) + data = @authentication.decrypt_payload(request_id, payload) + return unless data.is_a?(Hash) && data[:key] && data[:user_id] + @authentication.update(data) + end + + def self.update + self.new.update + end + + def self.destroy + self.new.destroy + end + + def self.generate_request + self.new.generate_request + end + + def self.handle_response + self.new.handle_response + end + def self.subscribed? self.new.subscribed? end + + def self.namespace + "custom_wizard_pro" + end end \ No newline at end of file diff --git a/lib/custom_wizard/pro/authentication.rb b/lib/custom_wizard/pro/authentication.rb index c92710bc..0d89ab06 100644 --- a/lib/custom_wizard/pro/authentication.rb +++ b/lib/custom_wizard/pro/authentication.rb @@ -1,10 +1,6 @@ class CustomWizard::ProAuthentication include ActiveModel::Serialization - API_KEY ||= "api_key" - API_CLIENT_ID ||= 'api_client_id' - KEYS ||= "keys" - attr_reader :client_id, :auth_by, :auth_at, @@ -39,10 +35,6 @@ class CustomWizard::ProAuthentication remove end - def self.destroy - self.new.destroy - end - def generate_keys(user_id, request_id) rsa = OpenSSL::PKey::RSA.generate(2048) nonce = SecureRandom.hex(32) @@ -72,37 +64,22 @@ class CustomWizard::ProAuthentication data end - def self.generate_request(user_id, request_id) - authentication = self.new - keys = authentication.generate_keys(user_id, request_id) - - params = { - public_key: keys.public_key, - nonce: keys.nonce, - client_id: authentication.client_id, - auth_redirect: "#{Discourse.base_url}/admin/wizards/pro/authorize/callback", - application_name: SiteSetting.title, - scopes: CustomWizard::ProSubscription::SCOPE - } - - uri = URI.parse("https://#{CustomWizard::ProSubscription::SUBSCRIPTION_SERVER}/user-api-key/new") - uri.query = URI.encode_www_form(params) - uri.to_s - end - - def self.handle_response(request_id, payload) - authentication = self.new - - data = authentication.decrypt_payload(request_id, payload) - return unless data.is_a?(Hash) && data[:key] && data[:user_id] - - authentication.update(data) - end - private + def api_key_db_key + "api_key" + end + + def api_client_id_db_key + "api_client_id" + end + + def keys_db_key + "keys" + end + def get_api_key - raw = PluginStore.get(CustomWizard::Pro::NAMESPACE, API_KEY) + raw = PluginStore.get(CustomWizard::Pro.namespace, api_key_db_key) OpenStruct.new( key: raw && raw['key'], auth_by: raw && raw['auth_by'], @@ -111,7 +88,7 @@ class CustomWizard::ProAuthentication end def set_api_key(key, user_id) - PluginStore.set(CustomWizard::Pro::NAMESPACE, API_KEY, + PluginStore.set(CustomWizard::Pro.namespace, api_key_db_key, key: key, auth_by: user_id, auth_at: Time.now @@ -119,21 +96,21 @@ class CustomWizard::ProAuthentication end def remove - PluginStore.remove(CustomWizard::Pro::NAMESPACE, API_KEY) + PluginStore.remove(CustomWizard::Pro.namespace, api_key_db_key) end def get_client_id - PluginStore.get(CustomWizard::Pro::NAMESPACE, API_CLIENT_ID) + PluginStore.get(CustomWizard::Pro.namespace, api_client_id_db_key) end def set_client_id client_id = SecureRandom.hex(32) - PluginStore.set(CustomWizard::Pro::NAMESPACE, API_CLIENT_ID, client_id) + PluginStore.set(CustomWizard::Pro.namespace, api_client_id_db_key, client_id) client_id end def set_keys(request_id, user_id, rsa, nonce) - PluginStore.set(CustomWizard::Pro::NAMESPACE, "#{KEYS}_#{request_id}", + PluginStore.set(CustomWizard::Pro.namespace, "#{keys_db_key}_#{request_id}", user_id: user_id, pem: rsa.export, nonce: nonce @@ -141,7 +118,7 @@ class CustomWizard::ProAuthentication end def get_keys(request_id) - raw = PluginStore.get(CustomWizard::Pro::NAMESPACE, "#{KEYS}_#{request_id}") + raw = PluginStore.get(CustomWizard::Pro.namespace, "#{keys_db_key}_#{request_id}") OpenStruct.new( user_id: raw && raw['user_id'], pem: raw && raw['pem'], @@ -150,6 +127,6 @@ class CustomWizard::ProAuthentication end def delete_keys(request_id) - PluginStore.remove(CustomWizard::Pro::NAMESPACE, "#{KEYS}_#{request_id}") + PluginStore.remove(CustomWizard::Pro.namespace, "#{keys_db_key}_#{request_id}") end end \ No newline at end of file diff --git a/lib/custom_wizard/pro/subscription.rb b/lib/custom_wizard/pro/subscription.rb index ef0ac2b9..f82b58df 100644 --- a/lib/custom_wizard/pro/subscription.rb +++ b/lib/custom_wizard/pro/subscription.rb @@ -1,14 +1,6 @@ class CustomWizard::ProSubscription include ActiveModel::Serialization - SUBSCRIPTION_SERVER ||= "test.thepavilion.io" - SUBSCRIPTION_TYPE ||= "stripe" - SCOPE ||= "discourse-subscription-server:user_subscription" - CLIENT_NAME ||= "custom-wizard" - SUBSCRIPTION_KEY ||= "custom_wizard_pro_subscription" - UPDATE_DAY_BUFFER ||= 2 - TYPES ||= %w(community business) - attr_reader :type, :updated_at @@ -21,8 +13,12 @@ class CustomWizard::ProSubscription end end + def types + %w(community business) + end + def active? - TYPES.include?(type) && updated_at.to_datetime > (Date.today - UPDATE_DAY_BUFFER.days).to_datetime + types.include?(type) && updated_at.to_datetime > (Date.today - 15.minutes).to_datetime end def update(data) @@ -37,39 +33,25 @@ class CustomWizard::ProSubscription end end - def self.update - auth = CustomWizard::ProAuthentication.new - subscription = self.new - - if auth.active? - response = Excon.get( - "https://#{SUBSCRIPTION_SERVER}/subscription-server/user-subscriptions/#{SUBSCRIPTION_TYPE}/#{CLIENT_NAME}", - headers: { - "User-Api-Key" => auth.api_key - } - ) - - if response.status == 200 - begin - data = JSON.parse(response.body).deep_symbolize_keys - rescue JSON::ParserError - return false - end - - return subscription.update(data) - end - end - - false + def destroy + remove end - + private - + + def key + "custom_wizard_pro_subscription" + end + def set(type) - PluginStore.set(CustomWizard::Pro::NAMESPACE, SUBSCRIPTION_KEY, type: type, updated_at: Time.now) + PluginStore.set(CustomWizard::Pro.namespace, key, type: type, updated_at: Time.now) end def get - PluginStore.get(CustomWizard::Pro::NAMESPACE, SUBSCRIPTION_KEY) + PluginStore.get(CustomWizard::Pro.namespace, key) + end + + def remove + PluginStore.remove(CustomWizard::Pro.namespace, key) end end \ No newline at end of file