mno-enterprise-core 3.2.1 → 3.3.0
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 +4 -4
 - data/app/controllers/mno_enterprise/application_controller.rb +5 -5
 - data/app/helpers/mno_enterprise/image_helper.rb +32 -0
 - data/app/models/mno_enterprise/app.rb +11 -2
 - data/app/models/mno_enterprise/base_resource.rb +2 -0
 - data/app/models/mno_enterprise/credit_card.rb +7 -4
 - data/app/models/mno_enterprise/impac/dashboard.rb +4 -1
 - data/app/models/mno_enterprise/impac/widget.rb +10 -4
 - data/app/models/mno_enterprise/org_invite.rb +7 -3
 - data/app/models/mno_enterprise/shared_entity.rb +17 -0
 - data/app/models/mno_enterprise/user.rb +7 -2
 - data/app/pdf/mno_enterprise/invoice_pdf.rb +176 -183
 - data/app/views/system_notifications/email-change.html.erb +1 -1
 - data/app/views/system_notifications/email-change.text.erb +1 -1
 - data/config/initializers/audit_log.rb +28 -1
 - data/config/locales/templates/components/en.yml +29 -4
 - data/config/locales/templates/dashboard/en.yml +2 -2
 - data/config/locales/templates/dashboard/marketplace/en.yml +5 -5
 - data/config/locales/templates/dashboard/organization/en.yml +14 -8
 - data/config/locales/templates/dashboard/organization/id.yml +4 -4
 - data/config/locales/templates/dashboard/organization/zh.yml +4 -4
 - data/config/locales/templates/dashboard/teams/en.yml +3 -3
 - data/config/locales/templates/dashboard/teams/id.yml +3 -3
 - data/config/locales/templates/dashboard/teams/zh.yml +3 -3
 - data/config/locales/templates/onboarding/en.yml +45 -0
 - data/config/locales/views/auth/confirmations/en.yml +5 -3
 - data/config/locales/views/webhook/o_auth/providers/en.yml +2 -2
 - data/lib/generators/mno_enterprise/install/install_generator.rb +19 -1
 - data/lib/generators/mno_enterprise/install/templates/Procfile.dev +1 -0
 - data/lib/generators/mno_enterprise/install/templates/config/initializers/mno_enterprise.rb +7 -50
 - data/lib/generators/mno_enterprise/install/templates/config/newrelic.yml +3 -3
 - data/lib/generators/mno_enterprise/install/templates/config/settings.yml +49 -2
 - data/lib/generators/mno_enterprise/install/templates/nginx.conf +71 -0
 - data/lib/generators/mno_enterprise/install/templates/stylesheets/variables.less +148 -141
 - data/lib/html_processor.rb +14 -14
 - data/lib/mno_enterprise/concerns/controllers/auth/registrations_controller.rb +18 -15
 - data/lib/mno_enterprise/concerns/models/ability.rb +6 -3
 - data/lib/mno_enterprise/concerns/models/app_instance.rb +2 -3
 - data/lib/mno_enterprise/concerns/models/intercom_user.rb +22 -0
 - data/lib/mno_enterprise/concerns/models/organization.rb +8 -0
 - data/lib/mno_enterprise/concerns/models/shared_entity.rb +36 -0
 - data/lib/mno_enterprise/concerns/models/team.rb +7 -0
 - data/lib/mno_enterprise/testing_support/common_rake.rb +1 -1
 - data/lib/mno_enterprise/testing_support/factories/apps.rb +6 -0
 - data/lib/mno_enterprise/testing_support/factories/audit_event.rb +2 -0
 - data/lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb +47 -16
 - data/lib/mno_enterprise/testing_support/organizations_shared_helpers.rb +6 -9
 - data/lib/mno_enterprise/version.rb +1 -1
 - data/spec/config/initializers/audit_log_spec.rb +5 -0
 - data/spec/controllers/mno_enterprise/application_controller_spec.rb +4 -4
 - data/spec/helpers/image_helper_spec.rb +69 -0
 - data/spec/models/mno_enterprise/ability_spec.rb +5 -0
 - data/spec/models/mno_enterprise/app_spec.rb +1 -1
 - data/spec/models/mno_enterprise/base_resource_spec.rb +37 -0
 - data/spec/models/mno_enterprise/credit_card_spec.rb +18 -0
 - data/spec/models/mno_enterprise/organization_spec.rb +16 -0
 - data/spec/models/mno_enterprise/shared_entity_spec.rb +7 -0
 - data/spec/models/mno_enterprise/user_spec.rb +83 -15
 - metadata +15 -2
 
    
        data/lib/html_processor.rb
    CHANGED
    
    | 
         @@ -8,13 +8,13 @@ require 'sanitize' 
     | 
|
| 
       8 
8 
     | 
    
         
             
            # You can initialize it with html or markdown text
         
     | 
| 
       9 
9 
     | 
    
         
             
            class HtmlProcessor
         
     | 
| 
       10 
10 
     | 
    
         
             
              attr_reader :html, :original
         
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
       12 
12 
     | 
    
         
             
              #======================================
         
     | 
| 
       13 
13 
     | 
    
         
             
              # Constants
         
     | 
| 
       14 
14 
     | 
    
         
             
              #======================================
         
     | 
| 
       15 
15 
     | 
    
         
             
              DESCRIPTION_PROCESSING_ORDER = %w( p h1 h2 h3 h4 h5 h6 )
         
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       18 
18 
     | 
    
         
             
              # Define Youtube transformer for Sanitize
         
     | 
| 
       19 
19 
     | 
    
         
             
              YOUTUBE_TRANSFORMER = lambda do |env|
         
     | 
| 
       20 
20 
     | 
    
         
             
                node      = env[:node]
         
     | 
| 
         @@ -45,7 +45,7 @@ class HtmlProcessor 
     | 
|
| 
       45 
45 
     | 
    
         
             
                # to whitelist the current node.
         
     | 
| 
       46 
46 
     | 
    
         
             
                {:node_whitelist => [node]}
         
     | 
| 
       47 
47 
     | 
    
         
             
              end
         
     | 
| 
       48 
     | 
    
         
            -
             
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
       49 
49 
     | 
    
         
             
              # Default options for Sanitize
         
     | 
| 
       50 
50 
     | 
    
         
             
              SANITIZER_OPTS = Sanitize::Config::RELAXED.merge(
         
     | 
| 
       51 
51 
     | 
    
         
             
                attributes: Sanitize::Config::RELAXED[:attributes].merge(
         
     | 
| 
         @@ -53,18 +53,18 @@ class HtmlProcessor 
     | 
|
| 
       53 
53 
     | 
    
         
             
                ),
         
     | 
| 
       54 
54 
     | 
    
         
             
                transformers: YOUTUBE_TRANSFORMER
         
     | 
| 
       55 
55 
     | 
    
         
             
              )
         
     | 
| 
       56 
     | 
    
         
            -
             
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
       57 
57 
     | 
    
         
             
              #======================================
         
     | 
| 
       58 
58 
     | 
    
         
             
              # Methods
         
     | 
| 
       59 
59 
     | 
    
         
             
              #======================================
         
     | 
| 
       60 
60 
     | 
    
         
             
              def initialize(text, options = { })
         
     | 
| 
       61 
61 
     | 
    
         
             
                @original = text
         
     | 
| 
       62 
     | 
    
         
            -
             
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
       63 
63 
     | 
    
         
             
                # Process markdown or leave original
         
     | 
| 
       64 
64 
     | 
    
         
             
                if options[:format].to_s == 'markdown' && text
         
     | 
| 
       65 
65 
     | 
    
         
             
                  html_options = { :safe_links_only => true, :hard_wrap => true, :filter_html => false }
         
     | 
| 
       66 
66 
     | 
    
         
             
                  renderer_options = { :autolink => true, :no_intraemphasis => true, :fenced_code_blocks => true, :superscript => true }
         
     | 
| 
       67 
     | 
    
         
            -
             
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
       68 
68 
     | 
    
         
             
                  renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new(html_options), renderer_options)
         
     | 
| 
       69 
69 
     | 
    
         
             
                  raw_html = renderer.render(text)
         
     | 
| 
       70 
70 
     | 
    
         
             
                  @html = Sanitize.fragment(raw_html, SANITIZER_OPTS)
         
     | 
| 
         @@ -72,27 +72,27 @@ class HtmlProcessor 
     | 
|
| 
       72 
72 
     | 
    
         
             
                  @html = text
         
     | 
| 
       73 
73 
     | 
    
         
             
                end
         
     | 
| 
       74 
74 
     | 
    
         
             
              end
         
     | 
| 
       75 
     | 
    
         
            -
             
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
       76 
76 
     | 
    
         
             
              # Return a Nokogiri document based
         
     | 
| 
       77 
77 
     | 
    
         
             
              # on processor html
         
     | 
| 
       78 
78 
     | 
    
         
             
              def document
         
     | 
| 
       79 
79 
     | 
    
         
             
                @document ||= Nokogiri::HTML(@html)
         
     | 
| 
       80 
80 
     | 
    
         
             
              end
         
     | 
| 
       81 
     | 
    
         
            -
             
     | 
| 
      
 81 
     | 
    
         
            +
             
     | 
| 
       82 
82 
     | 
    
         
             
              # Return a description of the document
         
     | 
| 
       83 
83 
     | 
    
         
             
              # by returning the first sentence of the
         
     | 
| 
       84 
84 
     | 
    
         
             
              # first DESCRIPTION_PROCESSING_ORDER found
         
     | 
| 
       85 
85 
     | 
    
         
             
              def description
         
     | 
| 
       86 
86 
     | 
    
         
             
                # Return cached value if one
         
     | 
| 
       87 
87 
     | 
    
         
             
                return @description if @description
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
       89 
89 
     | 
    
         
             
                # Parse the html document to try to find
         
     | 
| 
       90 
90 
     | 
    
         
             
                # a description
         
     | 
| 
       91 
91 
     | 
    
         
             
                @description = ''
         
     | 
| 
       92 
92 
     | 
    
         
             
                DESCRIPTION_PROCESSING_ORDER.each do |selector|
         
     | 
| 
       93 
     | 
    
         
            -
                  elem = self.document.css(selector). 
     | 
| 
      
 93 
     | 
    
         
            +
                  elem = self.document.css(selector).detect { |e| e && !e.content.blank? }
         
     | 
| 
       94 
94 
     | 
    
         
             
                  next if elem.blank? #skip if nil or empty
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
       96 
96 
     | 
    
         
             
                  # Try to get the first two sentences
         
     | 
| 
       97 
97 
     | 
    
         
             
                  match = elem.content.match(/([^.!?]+[.!?]?)([^.!?]+[.!?]?)?/)
         
     | 
| 
       98 
98 
     | 
    
         
             
                  if match && match.captures.any?
         
     | 
| 
         @@ -100,7 +100,7 @@ class HtmlProcessor 
     | 
|
| 
       100 
100 
     | 
    
         
             
                  end
         
     | 
| 
       101 
101 
     | 
    
         
             
                  break if !@description.empty?
         
     | 
| 
       102 
102 
     | 
    
         
             
                end
         
     | 
| 
       103 
     | 
    
         
            -
             
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
       104 
104 
     | 
    
         
             
                return @description
         
     | 
| 
       105 
105 
     | 
    
         
             
              end
         
     | 
| 
       106 
     | 
    
         
            -
            end
         
     | 
| 
      
 106 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -1,6 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module MnoEnterprise::Concerns::Controllers::Auth::RegistrationsController
         
     | 
| 
       2 
2 
     | 
    
         
             
              extend ActiveSupport::Concern
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
       4 
4 
     | 
    
         
             
              #==================================================================
         
     | 
| 
       5 
5 
     | 
    
         
             
              # Included methods
         
     | 
| 
       6 
6 
     | 
    
         
             
              #==================================================================
         
     | 
| 
         @@ -9,22 +9,22 @@ module MnoEnterprise::Concerns::Controllers::Auth::RegistrationsController 
     | 
|
| 
       9 
9 
     | 
    
         
             
              included do
         
     | 
| 
       10 
10 
     | 
    
         
             
                before_filter :configure_sign_up_params, only: [:create]
         
     | 
| 
       11 
11 
     | 
    
         
             
                # before_filter :configure_account_update_params, only: [:update]
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
       13 
13 
     | 
    
         
             
                protected
         
     | 
| 
       14 
14 
     | 
    
         
             
                  def configure_sign_up_params
         
     | 
| 
       15 
15 
     | 
    
         
             
                    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(
         
     | 
| 
       16 
     | 
    
         
            -
                      :email, 
     | 
| 
       17 
     | 
    
         
            -
                      :password, 
     | 
| 
       18 
     | 
    
         
            -
                      :password_confirmation, 
     | 
| 
       19 
     | 
    
         
            -
                      :name, 
     | 
| 
      
 16 
     | 
    
         
            +
                      :email,
         
     | 
| 
      
 17 
     | 
    
         
            +
                      :password,
         
     | 
| 
      
 18 
     | 
    
         
            +
                      :password_confirmation,
         
     | 
| 
      
 19 
     | 
    
         
            +
                      :name,
         
     | 
| 
       20 
20 
     | 
    
         
             
                      :surname,
         
     | 
| 
       21 
21 
     | 
    
         
             
                      :company,
         
     | 
| 
       22 
22 
     | 
    
         
             
                      :phone,
         
     | 
| 
       23 
23 
     | 
    
         
             
                      :phone_country_code
         
     | 
| 
       24 
     | 
    
         
            -
                    )} 
     | 
| 
      
 24 
     | 
    
         
            +
                    )}
         
     | 
| 
       25 
25 
     | 
    
         
             
                  end
         
     | 
| 
       26 
26 
     | 
    
         
             
              end
         
     | 
| 
       27 
     | 
    
         
            -
             
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
       28 
28 
     | 
    
         
             
              #==================================================================
         
     | 
| 
       29 
29 
     | 
    
         
             
              # Class methods
         
     | 
| 
       30 
30 
     | 
    
         
             
              #==================================================================
         
     | 
| 
         @@ -33,7 +33,7 @@ module MnoEnterprise::Concerns::Controllers::Auth::RegistrationsController 
     | 
|
| 
       33 
33 
     | 
    
         
             
                #   'some text'
         
     | 
| 
       34 
34 
     | 
    
         
             
                # end
         
     | 
| 
       35 
35 
     | 
    
         
             
              end
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
       37 
37 
     | 
    
         
             
              #==================================================================
         
     | 
| 
       38 
38 
     | 
    
         
             
              # Instance methods
         
     | 
| 
       39 
39 
     | 
    
         
             
              #==================================================================
         
     | 
| 
         @@ -46,10 +46,13 @@ module MnoEnterprise::Concerns::Controllers::Auth::RegistrationsController 
     | 
|
| 
       46 
46 
     | 
    
         
             
              def create
         
     | 
| 
       47 
47 
     | 
    
         
             
                build_resource(sign_up_params)
         
     | 
| 
       48 
48 
     | 
    
         
             
                resource.password ||= Devise.friendly_token
         
     | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
       50 
50 
     | 
    
         
             
                resource_saved = resource.save
         
     | 
| 
       51 
     | 
    
         
            -
             
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
       52 
52 
     | 
    
         
             
                if resource_saved
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  MnoEnterprise::EventLogger.info('user_add', resource_saved.id, 'User Signup', resource_saved)
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
       53 
56 
     | 
    
         
             
                  if resource.active_for_authentication?
         
     | 
| 
       54 
57 
     | 
    
         
             
                    set_flash_message :notice, :signed_up if is_flashing_format?
         
     | 
| 
       55 
58 
     | 
    
         
             
                    sign_up(resource_name, resource)
         
     | 
| 
         @@ -97,7 +100,7 @@ module MnoEnterprise::Concerns::Controllers::Auth::RegistrationsController 
     | 
|
| 
       97 
100 
     | 
    
         
             
              # end
         
     | 
| 
       98 
101 
     | 
    
         | 
| 
       99 
102 
     | 
    
         
             
              protected
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
       101 
104 
     | 
    
         
             
                # You can put the params you want to permit in the empty array.
         
     | 
| 
       102 
105 
     | 
    
         
             
                # def configure_account_update_params
         
     | 
| 
       103 
106 
     | 
    
         
             
                #   devise_parameter_sanitizer.for(:account_update) << :attribute
         
     | 
| 
         @@ -112,12 +115,12 @@ module MnoEnterprise::Concerns::Controllers::Auth::RegistrationsController 
     | 
|
| 
       112 
115 
     | 
    
         
             
                # def after_inactive_sign_up_path_for(resource)
         
     | 
| 
       113 
116 
     | 
    
         
             
                #   super(resource)
         
     | 
| 
       114 
117 
     | 
    
         
             
                # end
         
     | 
| 
       115 
     | 
    
         
            -
             
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
       116 
119 
     | 
    
         
             
                def sign_up_params
         
     | 
| 
       117 
120 
     | 
    
         
             
                  attrs = super
         
     | 
| 
       118 
121 
     | 
    
         
             
                  attrs.merge(orga_on_create: create_orga_on_user_creation(attrs))
         
     | 
| 
       119 
122 
     | 
    
         
             
                end
         
     | 
| 
       120 
     | 
    
         
            -
             
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
       121 
124 
     | 
    
         
             
                # Check whether we should create an organization for the user
         
     | 
| 
       122 
125 
     | 
    
         
             
                def create_orga_on_user_creation(user_attrs)
         
     | 
| 
       123 
126 
     | 
    
         
             
                  return false unless user_attrs['email']
         
     | 
| 
         @@ -133,4 +136,4 @@ module MnoEnterprise::Concerns::Controllers::Auth::RegistrationsController 
     | 
|
| 
       133 
136 
     | 
    
         
             
                  # Get remaining invites via email address
         
     | 
| 
       134 
137 
     | 
    
         
             
                  return MnoEnterprise::OrgInvite.where(user_email: user_attrs['email']).empty?
         
     | 
| 
       135 
138 
     | 
    
         
             
                end
         
     | 
| 
       136 
     | 
    
         
            -
            end
         
     | 
| 
      
 139 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -129,8 +129,11 @@ module MnoEnterprise::Concerns::Models::Ability 
     | 
|
| 
       129 
129 
     | 
    
         
             
                end
         
     | 
| 
       130 
130 
     | 
    
         | 
| 
       131 
131 
     | 
    
         
             
                can :manage_kpi, MnoEnterprise::Impac::Kpi do |kpi|
         
     | 
| 
       132 
     | 
    
         
            -
                   
     | 
| 
       133 
     | 
    
         
            -
             
     | 
| 
      
 132 
     | 
    
         
            +
                  if kpi.widget.present?
         
     | 
| 
      
 133 
     | 
    
         
            +
                    authorize! :manage_widget, MnoEnterprise::Impac::Widget.find(kpi.widget.id)
         
     | 
| 
      
 134 
     | 
    
         
            +
                  else
         
     | 
| 
      
 135 
     | 
    
         
            +
                    authorize! :manage_dashboard, kpi.dashboard
         
     | 
| 
      
 136 
     | 
    
         
            +
                  end
         
     | 
| 
       134 
137 
     | 
    
         
             
                end
         
     | 
| 
       135 
138 
     | 
    
         | 
| 
       136 
139 
     | 
    
         
             
                can :manage_alert, MnoEnterprise::Impac::Alert do |alert|
         
     | 
| 
         @@ -141,7 +144,7 @@ module MnoEnterprise::Concerns::Models::Ability 
     | 
|
| 
       141 
144 
     | 
    
         | 
| 
       142 
145 
     | 
    
         
             
              # Abilities for admin user
         
     | 
| 
       143 
146 
     | 
    
         
             
              def admin_abilities(user)
         
     | 
| 
       144 
     | 
    
         
            -
                if user.admin_role 
     | 
| 
      
 147 
     | 
    
         
            +
                if user.admin_role.to_s.casecmp('admin').zero?
         
     | 
| 
       145 
148 
     | 
    
         
             
                  can :manage_app_instances, MnoEnterprise::Organization
         
     | 
| 
       146 
149 
     | 
    
         
             
                end
         
     | 
| 
       147 
150 
     | 
    
         
             
              end
         
     | 
| 
         @@ -25,4 +25,26 @@ module MnoEnterprise::Concerns::Models::IntercomUser 
     | 
|
| 
       25 
25 
     | 
    
         
             
              def intercom_user_hash
         
     | 
| 
       26 
26 
     | 
    
         
             
                OpenSSL::HMAC.hexdigest('sha256', MnoEnterprise.intercom_api_secret, (self.id || self.email).to_s) if MnoEnterprise.intercom_api_secret
         
     | 
| 
       27 
27 
     | 
    
         
             
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              # Return Intercom user data hash
         
     | 
| 
      
 30 
     | 
    
         
            +
              def intercom_data(update_last_request_at = true)
         
     | 
| 
      
 31 
     | 
    
         
            +
                data = {
         
     | 
| 
      
 32 
     | 
    
         
            +
                  user_id: self.id,
         
     | 
| 
      
 33 
     | 
    
         
            +
                  name: [self.name, self.surname].join(' '),
         
     | 
| 
      
 34 
     | 
    
         
            +
                  email: self.email,
         
     | 
| 
      
 35 
     | 
    
         
            +
                  created_at: self.created_at.to_i,
         
     | 
| 
      
 36 
     | 
    
         
            +
                  last_seen_ip: self.last_sign_in_ip,
         
     | 
| 
      
 37 
     | 
    
         
            +
                  custom_attributes: {
         
     | 
| 
      
 38 
     | 
    
         
            +
                    first_name: self.name,
         
     | 
| 
      
 39 
     | 
    
         
            +
                    surname: self.surname,
         
     | 
| 
      
 40 
     | 
    
         
            +
                    confirmed_at: self.confirmed_at,
         
     | 
| 
      
 41 
     | 
    
         
            +
                    admin_role: self.admin_role
         
     | 
| 
      
 42 
     | 
    
         
            +
                  },
         
     | 
| 
      
 43 
     | 
    
         
            +
                  update_last_request_at: update_last_request_at
         
     | 
| 
      
 44 
     | 
    
         
            +
                }
         
     | 
| 
      
 45 
     | 
    
         
            +
                data[:custom_attributes][:phone]= self.phone if self.phone
         
     | 
| 
      
 46 
     | 
    
         
            +
                data[:custom_attributes][:external_id]= self.external_id if self.external_id
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                data
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
       28 
50 
     | 
    
         
             
            end
         
     | 
| 
         @@ -41,6 +41,10 @@ module MnoEnterprise::Concerns::Models::Organization 
     | 
|
| 
       41 
41 
     | 
    
         | 
| 
       42 
42 
     | 
    
         
             
                scope :in_arrears, -> { where(in_arrears?: true) }
         
     | 
| 
       43 
43 
     | 
    
         | 
| 
      
 44 
     | 
    
         
            +
                scope :active, -> { where(account_frozen: false) }
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                default_scope lambda { where(account_frozen: false) }
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
       44 
48 
     | 
    
         
             
                #================================
         
     | 
| 
       45 
49 
     | 
    
         
             
                # Associations
         
     | 
| 
       46 
50 
     | 
    
         
             
                #================================
         
     | 
| 
         @@ -115,4 +119,8 @@ module MnoEnterprise::Concerns::Models::Organization 
     | 
|
| 
       115 
119 
     | 
    
         
             
              def payment_restriction
         
     | 
| 
       116 
120 
     | 
    
         
             
                meta_data && meta_data['payment_restriction']
         
     | 
| 
       117 
121 
     | 
    
         
             
              end
         
     | 
| 
      
 122 
     | 
    
         
            +
             
     | 
| 
      
 123 
     | 
    
         
            +
              def has_credit_card_details?
         
     | 
| 
      
 124 
     | 
    
         
            +
                credit_card.persisted?
         
     | 
| 
      
 125 
     | 
    
         
            +
              end
         
     | 
| 
       118 
126 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,36 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
            # == Schema Information
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Endpoint:
         
     | 
| 
      
 5 
     | 
    
         
            +
            #  - /v1/app/:app_id/shared_entities
         
     | 
| 
      
 6 
     | 
    
         
            +
            #
         
     | 
| 
      
 7 
     | 
    
         
            +
            #  id                :integer         not null, primary key
         
     | 
| 
      
 8 
     | 
    
         
            +
            #  nid               :string
         
     | 
| 
      
 9 
     | 
    
         
            +
            #  name              :string
         
     | 
| 
      
 10 
     | 
    
         
            +
            #  created_at        :datetime        not null
         
     | 
| 
      
 11 
     | 
    
         
            +
            #  updated_at        :datetime        not null
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            module MnoEnterprise::Concerns::Models::SharedEntity
         
     | 
| 
      
 14 
     | 
    
         
            +
              extend ActiveSupport::Concern
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              #==================================================================
         
     | 
| 
      
 17 
     | 
    
         
            +
              # Included methods
         
     | 
| 
      
 18 
     | 
    
         
            +
              #==================================================================
         
     | 
| 
      
 19 
     | 
    
         
            +
              included do
         
     | 
| 
      
 20 
     | 
    
         
            +
                # == Relationships ==============================================
         
     | 
| 
      
 21 
     | 
    
         
            +
                belongs_to :app
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              #==================================================================
         
     | 
| 
      
 25 
     | 
    
         
            +
              # Class methods
         
     | 
| 
      
 26 
     | 
    
         
            +
              #==================================================================
         
     | 
| 
      
 27 
     | 
    
         
            +
              module ClassMethods
         
     | 
| 
      
 28 
     | 
    
         
            +
                # def some_class_method
         
     | 
| 
      
 29 
     | 
    
         
            +
                #   'some text'
         
     | 
| 
      
 30 
     | 
    
         
            +
                # end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              #==================================================================
         
     | 
| 
      
 34 
     | 
    
         
            +
              # Instance methods
         
     | 
| 
      
 35 
     | 
    
         
            +
              #==================================================================
         
     | 
| 
      
 36 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -13,7 +13,7 @@ namespace :mno_enterprise do 
     | 
|
| 
       13 
13 
     | 
    
         
             
                  ENV["RAILS_ENV"] = 'test'
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
       15 
15 
     | 
    
         
             
                  MnoEnterprise::DummyGenerator.start %W[--quiet --lib_name=#{ENV['LIB_NAME']} --database=#{ENV['DB'].presence || 'sqlite3'}]
         
     | 
| 
       16 
     | 
    
         
            -
                  MnoEnterprise::Generators::InstallGenerator.start %w[--quiet --skip-rspec --skip-sprite --skip-factory-girl --skip-frontend --skip-admin]
         
     | 
| 
      
 16 
     | 
    
         
            +
                  MnoEnterprise::Generators::InstallGenerator.start %w[--quiet --skip-rspec --skip-sprite --skip-factory-girl --skip-application-config --skip-frontend --skip-admin]
         
     | 
| 
       17 
17 
     | 
    
         
             
                end
         
     | 
| 
       18 
18 
     | 
    
         
             
              end
         
     | 
| 
       19 
19 
     | 
    
         
             
            end
         
     | 
| 
         @@ -16,11 +16,15 @@ FactoryGirl.define do 
     | 
|
| 
       16 
16 
     | 
    
         
             
                tags ['Foo', 'Bar']
         
     | 
| 
       17 
17 
     | 
    
         
             
                key_benefits ['Super', 'Hyper', 'Good']
         
     | 
| 
       18 
18 
     | 
    
         
             
                key_features ['Super', 'Hyper', 'Good']
         
     | 
| 
      
 19 
     | 
    
         
            +
                key_workflows ['1st workflow', '2nd workflow']
         
     | 
| 
      
 20 
     | 
    
         
            +
                known_limitations "No limitations"
         
     | 
| 
       19 
21 
     | 
    
         
             
                testimonials [{text: 'Bla', company: 'Doe Pty Ltd', author: 'John'}]
         
     | 
| 
       20 
22 
     | 
    
         
             
                worldwide_usage 120000
         
     | 
| 
       21 
23 
     | 
    
         
             
                tiny_description "A great app"
         
     | 
| 
       22 
24 
     | 
    
         
             
                stack 'cube'
         
     | 
| 
       23 
25 
     | 
    
         
             
                terms_url "http://opensource.org/licenses/MIT"
         
     | 
| 
      
 26 
     | 
    
         
            +
                support_url "http://example.com/su  pport"
         
     | 
| 
      
 27 
     | 
    
         
            +
                getting_started "Let's get started"
         
     | 
| 
       24 
28 
     | 
    
         
             
                appinfo { {} }
         
     | 
| 
       25 
29 
     | 
    
         
             
                average_rating { rand(1..5) }
         
     | 
| 
       26 
30 
     | 
    
         
             
                sequence(:rank) { |n| n }
         
     | 
| 
         @@ -29,6 +33,8 @@ FactoryGirl.define do 
     | 
|
| 
       29 
33 
     | 
    
         
             
                  'default' => [{name: 'Monthly Plan', price: '20.0', currency: 'AUD', factor: '/month'}]
         
     | 
| 
       30 
34 
     | 
    
         
             
                } }
         
     | 
| 
       31 
35 
     | 
    
         | 
| 
      
 36 
     | 
    
         
            +
                shared_entities { [] }
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
       32 
38 
     | 
    
         
             
                trait :cloud do
         
     | 
| 
       33 
39 
     | 
    
         
             
                  stack 'cloud'
         
     | 
| 
       34 
40 
     | 
    
         
             
                end
         
     | 
| 
         @@ -1,12 +1,12 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            module MnoEnterpriseApiTestHelper
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       3 
3 
     | 
    
         
             
              # Take a resource and transform it into a Hash describing
         
     | 
| 
       4 
4 
     | 
    
         
             
              # the resource as if it had been returned by the MnoEnterprise
         
     | 
| 
       5 
5 
     | 
    
         
             
              # API server
         
     | 
| 
       6 
6 
     | 
    
         
             
              def from_api(res)
         
     | 
| 
       7 
7 
     | 
    
         
             
                { data: serialize_type(res), metadata: {pagination: {count: entity_count(res)}} }
         
     | 
| 
       8 
8 
     | 
    
         
             
              end
         
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
       10 
10 
     | 
    
         
             
              def serialize_type(res)
         
     | 
| 
       11 
11 
     | 
    
         
             
                case
         
     | 
| 
       12 
12 
     | 
    
         
             
                when res.kind_of?(Array)
         
     | 
| 
         @@ -42,7 +42,7 @@ module MnoEnterpriseApiTestHelper 
     | 
|
| 
       42 
42 
     | 
    
         
             
                  return 1
         
     | 
| 
       43 
43 
     | 
    
         
             
                end
         
     | 
| 
       44 
44 
     | 
    
         
             
              end
         
     | 
| 
       45 
     | 
    
         
            -
             
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
       46 
46 
     | 
    
         
             
              # Reset all API stubs.
         
     | 
| 
       47 
47 
     | 
    
         
             
              # Called before each test (see spec_helper)
         
     | 
| 
       48 
48 
     | 
    
         
             
              def api_stub_reset
         
     | 
| 
         @@ -74,12 +74,27 @@ module MnoEnterpriseApiTestHelper 
     | 
|
| 
       74 
74 
     | 
    
         
             
                  warn("DEPRECATION WARNING: api_stub_for(MyClass,{ some: 'opts'}) is deprecated. Please use api_stub_for({ some: 'opts' }) from now on")
         
     | 
| 
       75 
75 
     | 
    
         
             
                  real_opts = opts
         
     | 
| 
       76 
76 
     | 
    
         
             
                end
         
     | 
| 
       77 
     | 
    
         
            -
             
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
       78 
78 
     | 
    
         
             
                set_api_stub
         
     | 
| 
       79 
79 
     | 
    
         
             
                api_stub_add(real_opts)
         
     | 
| 
       80 
80 
     | 
    
         
             
                api_stub_configure(@_api_stub)
         
     | 
| 
       81 
81 
     | 
    
         
             
              end
         
     | 
| 
       82 
     | 
    
         
            -
             
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              # Remove an API stub added with `api_stub_for`
         
     | 
| 
      
 84 
     | 
    
         
            +
              # This needs to be called with the same options
         
     | 
| 
      
 85 
     | 
    
         
            +
              def remove_api_stub(opts = {})
         
     | 
| 
      
 86 
     | 
    
         
            +
                set_api_stub
         
     | 
| 
      
 87 
     | 
    
         
            +
                api_stub_remove(opts)
         
     | 
| 
      
 88 
     | 
    
         
            +
                api_stub_configure(@_api_stub)
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
              # Remove all api stubs
         
     | 
| 
      
 92 
     | 
    
         
            +
              def clear_api_stubs
         
     | 
| 
      
 93 
     | 
    
         
            +
                set_api_stub
         
     | 
| 
      
 94 
     | 
    
         
            +
                @_stub_list = {}
         
     | 
| 
      
 95 
     | 
    
         
            +
                api_stub_configure(@_api_stub)
         
     | 
| 
      
 96 
     | 
    
         
            +
              end
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
       83 
98 
     | 
    
         
             
              private
         
     | 
| 
       84 
99 
     | 
    
         
             
                # Set a stub api on the provider class
         
     | 
| 
       85 
100 
     | 
    
         
             
                def set_api_stub
         
     | 
| 
         @@ -99,21 +114,37 @@ module MnoEnterpriseApiTestHelper 
     | 
|
| 
       99 
114 
     | 
    
         
             
                def api_stub_add(orig_opts)
         
     | 
| 
       100 
115 
     | 
    
         
             
                  @_stub_list ||= {}
         
     | 
| 
       101 
116 
     | 
    
         
             
                  opts = orig_opts.dup
         
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
       103 
     | 
    
         
            -
                   
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                  expand_options(opts)
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                  key = opts.to_param
         
     | 
| 
      
 121 
     | 
    
         
            +
                  @_stub_list[key] = opts
         
     | 
| 
      
 122 
     | 
    
         
            +
                end
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
                # Remove an API
         
     | 
| 
      
 125 
     | 
    
         
            +
                # This need to be called with the exact same options as `api_stub_add` was called with
         
     | 
| 
      
 126 
     | 
    
         
            +
                def api_stub_remove(orig_opts)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  @_stub_list ||= {}
         
     | 
| 
      
 128 
     | 
    
         
            +
                  opts = orig_opts.dup
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                  expand_options(opts)
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                  key = opts.to_param
         
     | 
| 
      
 133 
     | 
    
         
            +
                  @_stub_list.delete(key)
         
     | 
| 
      
 134 
     | 
    
         
            +
                end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                # Expand options so that: { put: '/path' } becomes { path: '/path', method: :put }
         
     | 
| 
      
 137 
     | 
    
         
            +
                def expand_options(opts)
         
     | 
| 
       104 
138 
     | 
    
         
             
                  unless opts[:method] && opts[:path]
         
     | 
| 
       105 
     | 
    
         
            -
                    [:get 
     | 
| 
      
 139 
     | 
    
         
            +
                    [:get, :put, :post, :delete].each do |verb|
         
     | 
| 
       106 
140 
     | 
    
         
             
                      if path = opts.delete(verb)
         
     | 
| 
       107 
141 
     | 
    
         
             
                        opts[:path] = path
         
     | 
| 
       108 
142 
     | 
    
         
             
                        opts[:method] = verb
         
     | 
| 
       109 
143 
     | 
    
         
             
                      end
         
     | 
| 
       110 
144 
     | 
    
         
             
                    end
         
     | 
| 
       111 
145 
     | 
    
         
             
                  end
         
     | 
| 
       112 
     | 
    
         
            -
                  
         
     | 
| 
       113 
     | 
    
         
            -
                  key = opts.to_param
         
     | 
| 
       114 
     | 
    
         
            -
                  @_stub_list[key] = opts
         
     | 
| 
       115 
146 
     | 
    
         
             
                end
         
     | 
| 
       116 
     | 
    
         
            -
             
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
       117 
148 
     | 
    
         
             
                # Configure the api and apply a list of stubs
         
     | 
| 
       118 
149 
     | 
    
         
             
                def api_stub_configure(api)
         
     | 
| 
       119 
150 
     | 
    
         
             
                  # This block should match the her.rb initializer
         
     | 
| 
         @@ -157,12 +188,12 @@ module MnoEnterpriseApiTestHelper 
     | 
|
| 
       157 
188 
     | 
    
         
             
                          else
         
     | 
| 
       158 
189 
     | 
    
         
             
                            resp_code = stub[:code] || 200
         
     | 
| 
       159 
190 
     | 
    
         
             
                          end
         
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
       161 
     | 
    
         
            -
             
     | 
| 
       162 
     | 
    
         
            -
                          [resp_code, {}, resp.to_json] 
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                          [resp_code, {}, resp.to_json]
         
     | 
| 
       163 
194 
     | 
    
         
             
                        }
         
     | 
| 
       164 
195 
     | 
    
         
             
                      end
         
     | 
| 
       165 
196 
     | 
    
         
             
                    end
         
     | 
| 
       166 
197 
     | 
    
         
             
                  end
         
     | 
| 
       167 
198 
     | 
    
         
             
                end
         
     | 
| 
       168 
     | 
    
         
            -
            end
         
     | 
| 
      
 199 
     | 
    
         
            +
            end
         
     |