mno-enterprise-core 3.0.7 → 3.1.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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/images/mno_enterprise/login-background.jpg +0 -0
  3. data/app/assets/stylesheets/mno_enterprise/mail.css +27 -0
  4. data/app/helpers/mno_enterprise/application_helper.rb +14 -0
  5. data/app/helpers/mno_enterprise/impersonate_helper.rb +1 -1
  6. data/app/models/mno_enterprise/app.rb +2 -1
  7. data/app/models/mno_enterprise/base_resource.rb +1 -2
  8. data/app/models/mno_enterprise/impac/dashboard.rb +3 -1
  9. data/app/models/mno_enterprise/impac/kpi.rb +1 -1
  10. data/app/models/mno_enterprise/impac/widget.rb +1 -1
  11. data/app/models/mno_enterprise/org_invite.rb +2 -1
  12. data/app/models/mno_enterprise/tenant.rb +2 -4
  13. data/app/models/mno_enterprise/user.rb +6 -0
  14. data/app/pdf/mno_enterprise/invoice_pdf.rb +29 -12
  15. data/app/views/system_notifications/confirmation-instructions.html.erb +26 -0
  16. data/app/views/system_notifications/confirmation-instructions.text.erb +10 -0
  17. data/app/views/system_notifications/delete-request-instructions.html.erb +31 -0
  18. data/app/views/system_notifications/delete-request-instructions.text.erb +15 -0
  19. data/app/views/system_notifications/organization-invite-existing-user.html.erb +30 -0
  20. data/app/views/system_notifications/organization-invite-existing-user.text.erb +13 -0
  21. data/app/views/system_notifications/organization-invite-new-user.html.erb +30 -0
  22. data/app/views/system_notifications/organization-invite-new-user.text.erb +14 -0
  23. data/app/views/system_notifications/reconfirmation-instructions.html.erb +27 -0
  24. data/app/views/system_notifications/reconfirmation-instructions.text.erb +10 -0
  25. data/app/views/system_notifications/registration-instructions.html.erb +27 -0
  26. data/app/views/system_notifications/registration-instructions.text.erb +9 -0
  27. data/app/views/system_notifications/reset-password-instructions.html.erb +27 -0
  28. data/app/views/system_notifications/reset-password-instructions.text.erb +11 -0
  29. data/app/views/system_notifications/unlock-instructions.html.erb +27 -0
  30. data/app/views/system_notifications/unlock-instructions.text.erb +10 -0
  31. data/config/initializers/audit_log.rb +2 -0
  32. data/config/locales/templates/dashboard/organization/en.yml +2 -0
  33. data/config/locales/views/auth/registrations/en.yml +1 -1
  34. data/lib/devise/hooks/impersonatable.rb +14 -0
  35. data/lib/devise_extension.rb +9 -2
  36. data/lib/generators/mno_enterprise/install/templates/config/application.yml +6 -2
  37. data/lib/generators/mno_enterprise/install/templates/config/initializers/mno_enterprise.rb +6 -1
  38. data/lib/generators/mno_enterprise/install/templates/config/settings.yml +2 -0
  39. data/lib/generators/mno_enterprise/install/templates/config/settings/uat.yml +2 -2
  40. data/lib/generators/mno_enterprise/install/templates/stylesheets/main.less +4 -0
  41. data/lib/her_extension/model/relation.rb +0 -13
  42. data/lib/mandrill_client.rb +13 -41
  43. data/lib/mno_enterprise/concerns/models/ability.rb +12 -0
  44. data/lib/mno_enterprise/concerns/models/organization.rb +5 -2
  45. data/lib/mno_enterprise/core.rb +21 -8
  46. data/lib/mno_enterprise/mail_adapters/adapter.rb +51 -0
  47. data/lib/mno_enterprise/mail_adapters/mandrill_adapter.rb +39 -0
  48. data/lib/mno_enterprise/mail_adapters/smtp_adapter.rb +21 -0
  49. data/lib/mno_enterprise/mail_adapters/sparkpost_adapter.rb +56 -0
  50. data/lib/mno_enterprise/mail_adapters/test_adapter.rb +21 -0
  51. data/lib/mno_enterprise/mail_client.rb +28 -0
  52. data/lib/mno_enterprise/smtp_client.rb +32 -0
  53. data/lib/mno_enterprise/testing_support/factories/apps.rb +1 -2
  54. data/lib/mno_enterprise/testing_support/factories/impac/kpis.rb +1 -0
  55. data/lib/mno_enterprise/testing_support/factories/tenant.rb +1 -7
  56. data/lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb +1 -2
  57. data/lib/mno_enterprise/version.rb +1 -1
  58. data/spec/lib/her_extension/model/relation_spec.rb +0 -71
  59. data/spec/lib/mandrill_client_spec.rb +27 -42
  60. data/spec/lib/mno_enterprise/mail_adapters/adapter_spec.rb +29 -0
  61. data/spec/lib/mno_enterprise/mail_adapters/mandrill_adapter_spec.rb +53 -0
  62. data/spec/lib/mno_enterprise/mail_adapters/smtp_adapter_spec.rb +29 -0
  63. data/spec/lib/mno_enterprise/mail_adapters/sparkpost_adapter_spec.rb +60 -0
  64. data/spec/lib/mno_enterprise/mail_client_spec.rb +9 -0
  65. data/spec/lib/mno_enterprise/smtp_client_spec.rb +39 -0
  66. data/spec/models/mno_enterprise/ability_spec.rb +21 -0
  67. data/spec/models/mno_enterprise/base_resource_spec.rb +0 -22
  68. metadata +76 -24
  69. data/lib/her_extension/middleware/mnoe_raise_error.rb +0 -21
  70. data/lib/her_extension/model/associations/belongs_to_association.rb +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7e66a5aee69128edacb89198ee45091e47f122bf
4
- data.tar.gz: d44daad907fa1a756615b594da21d7c44501a297
3
+ metadata.gz: 1f6186245d5ffafcbdde4aebcb976b5ec4e841b2
4
+ data.tar.gz: d5ecb24f9f5be4a58bbd39b1ee0f1210c971d544
5
5
  SHA512:
6
- metadata.gz: 2b169ef2e75dc049271f3bc6a350716369485437483cf258d3674f4f480af0a448ed8d66ef8e76d361526715d752d31cd2619bc5ef1d12ec71e35db01a83f0e7
7
- data.tar.gz: 3cc52c2f2ba69f7612502bab7dc21017067a71b178e5c25e3d31a5a0dcb30fdfbfe1c20c9d3e3f8b785a2f731a85c17b9a34fa6a0b08a3f44ce8ee960788e638
6
+ metadata.gz: f0ed824978bc6d391744c66a0045e634bd4364c289796e4138bf2818955eac35f2957c27d9183c3e17d5e138b5c29fc7ddb91d765053606e4adda06d53b15a99
7
+ data.tar.gz: 665975695947ba02bae356968e139128006e258730e949bcd5e14709a39bf264e01f265e4a22d024c9f5ff5bb696606c238bfc22a0a39425da29d1f90e0f1c74
@@ -0,0 +1,27 @@
1
+ .header {
2
+ display: block;
3
+ width: 100%;
4
+
5
+ margin-bottom: 40px;
6
+ padding: 20px 0;
7
+ border-bottom: 1px solid #ccc;
8
+ }
9
+ .header img{
10
+ display: block;
11
+ width: 40%;
12
+ min-width: 200px;
13
+ max-width: 400px;
14
+
15
+ margin: 0 auto;
16
+ }
17
+
18
+ .footer {
19
+ margin-top: 40px;
20
+ padding: 10px 0 0;
21
+
22
+ text-align: right;
23
+ font-size: 15px;
24
+
25
+ color: #666;
26
+ border-top: 1px solid #ccc;
27
+ }
@@ -63,5 +63,19 @@ module MnoEnterprise
63
63
  return text unless text.present?
64
64
  HtmlProcessor.new(text, format: :markdown).html.html_safe
65
65
  end
66
+
67
+ # Return the user avatar url. The displayed picture use the gravatar of the user email
68
+ # TODO: add and use avatar_email from the OAUTH user
69
+ def avatar_url(user)
70
+ gravatar_url(user.email)
71
+ end
72
+
73
+ # Return the gravatar url for the given email
74
+ def gravatar_url(email)
75
+ if email
76
+ gravatar_id = Digest::MD5.hexdigest(email.downcase)
77
+ "https://gravatar.com/avatar/#{gravatar_id}.png?s=50&d=mm"
78
+ end
79
+ end
66
80
  end
67
81
  end
@@ -24,4 +24,4 @@ module MnoEnterprise
24
24
  end
25
25
 
26
26
  end
27
- end
27
+ end
@@ -22,6 +22,7 @@
22
22
  # stack :string(255)
23
23
  # terms_url :string(255)
24
24
  # tags :text
25
+ # rank :integer
25
26
  #
26
27
 
27
28
  module MnoEnterprise
@@ -31,7 +32,7 @@ module MnoEnterprise
31
32
 
32
33
  attributes :id, :uid, :nid, :name, :description, :tiny_description, :created_at, :updated_at, :logo, :website, :slug,
33
34
  :categories, :key_benefits, :key_features, :testimonials, :worldwide_usage, :tiny_description,
34
- :popup_description, :stack, :terms_url, :pictures, :tags, :api_key, :metadata_url, :metadata, :details
35
+ :popup_description, :stack, :terms_url, :pictures, :tags, :api_key, :metadata_url, :metadata, :details, :rank
35
36
 
36
37
  # Return the list of available categories
37
38
  def self.categories(list = nil)
@@ -143,8 +143,7 @@ module MnoEnterprise
143
143
  if perform_validations(options)
144
144
  ret = super()
145
145
  process_response_errors
146
- raise_record_invalid if self.errors.any?
147
- ret
146
+ raise_record_invalid
148
147
  else
149
148
  false
150
149
  end
@@ -19,7 +19,9 @@ module MnoEnterprise
19
19
  # Return all the organizations linked to this dashboard and to which
20
20
  # the user has access
21
21
  def organizations
22
- MnoEnterprise::Organization.where('uid.in' => self.organization_ids).to_a
22
+ self.organization_ids.map do |uid|
23
+ MnoEnterprise::Organization.find_by(uid: uid)
24
+ end
23
25
  end
24
26
 
25
27
  def sorted_widgets
@@ -1,7 +1,7 @@
1
1
  module MnoEnterprise
2
2
  class Impac::Kpi < BaseResource
3
3
 
4
- attributes :settings, :targets, :extra_params, :endpoint, :source, :element_watched
4
+ attributes :name, :settings, :targets, :extra_params, :endpoint, :source, :element_watched
5
5
 
6
6
  belongs_to :dashboard, class_name: 'MnoEnterprise::Impac::Dashboard'
7
7
 
@@ -1,7 +1,7 @@
1
1
  module MnoEnterprise
2
2
  class Impac::Widget < BaseResource
3
3
 
4
- attributes :name, :width, :widget_category, :settings
4
+ attributes :name, :width, :widget_category, :settings
5
5
 
6
6
  belongs_to :dashboard, class_name: 'MnoEnterprise::Impac::Dashboard'
7
7
 
@@ -20,6 +20,7 @@
20
20
  module MnoEnterprise
21
21
  class OrgInvite < BaseResource
22
22
  scope :active, -> { where(status: 'pending') }
23
+ scope :active_or_staged, -> { where('status.in' => %w(staged pending)) }
23
24
 
24
25
  #==============================================================
25
26
  # Associations
@@ -47,4 +48,4 @@ module MnoEnterprise
47
48
  self.status != 'pending' || self.created_at < 3.days.ago
48
49
  end
49
50
  end
50
- end
51
+ end
@@ -1,7 +1,5 @@
1
1
  module MnoEnterprise
2
2
  class Tenant < BaseResource
3
- def self.show
4
- self.get('tenant')
5
- end
3
+
6
4
  end
7
- end
5
+ end
@@ -56,6 +56,7 @@ module MnoEnterprise
56
56
  #================================
57
57
  # Validation
58
58
  #================================
59
+ validates_uniqueness_of :email, allow_blank: true, if: :email_changed?
59
60
 
60
61
  if Devise.password_regex
61
62
  validates :password, format: { with: Devise.password_regex, message: Devise.password_regex_message }, if: :password_required?
@@ -133,6 +134,11 @@ module MnoEnterprise
133
134
  @errors ||= ActiveModel::Errors.new(self)
134
135
  end
135
136
 
137
+ # Don't require a password for unconfirmed users (user save password at confirmation step)
138
+ def password_required?
139
+ super if confirmed?
140
+ end
141
+
136
142
  #================================
137
143
  # Instance Methods
138
144
  #================================
@@ -55,11 +55,11 @@ module MnoEnterprise
55
55
  # Billing details
56
56
  @data[:billing_report] = @invoice.billing_summary.map do |item|
57
57
  item_label = item[:label]
58
- price_label = item[:price_tag]
58
+ price_label = format_price item
59
59
 
60
60
  (item[:lines] || []).each do |item_line|
61
61
  item_label += "<font size='4'>\n\n</font><font size='8'><color rgb='999999'><i>#{Prawn::Text::NBSP * 3}#{item_line[:label]}</i></color></font>"
62
- price_label += "<font size='4'>\n\n</font><font size='8'><color rgb='999999'>#{item_line[:price_tag]}</color></font>"
62
+ price_label += "<font size='4'>\n\n</font><font size='8'><color rgb='999999'>#{format_price(item_line)}</color></font>"
63
63
  end
64
64
 
65
65
  [item_label, item[:name], item[:usage], price_label]
@@ -80,6 +80,17 @@ module MnoEnterprise
80
80
  @pdf.render
81
81
  end
82
82
 
83
+ def format_price(item)
84
+ # price_tag is deprecated
85
+ price = item[:price]
86
+ if price
87
+ # Money hash are automatically parsed to Money in core/lib/her_extension/middleware/mnoe_api_v1_parse_json.rb
88
+ money(price)
89
+ else
90
+ item[:price_tag]
91
+ end
92
+ end
93
+
83
94
  # Generate the document content
84
95
  # by adding body, header, footer and
85
96
  # page numbering
@@ -116,6 +127,12 @@ module MnoEnterprise
116
127
  File.exists?(app_path) ? app_path : engine_path
117
128
  end
118
129
 
130
+ # Format a money object
131
+ def money(m)
132
+ "#{m.format(symbol: false)} #{m.currency_as_string}"
133
+ end
134
+
135
+
119
136
  # Add a repeated header to the document
120
137
  def add_page_header
121
138
  @pdf.repeat :all do
@@ -206,7 +223,7 @@ module MnoEnterprise
206
223
 
207
224
  summary_data = []
208
225
  summary_data << ['Period', 'Total Payable' + (@data[:invoice_tax_pips] > 0 ? "\n<font size='8'><i>(incl. GST)</i></font>" : '')]
209
- summary_data << ["#{@data[:period_started_at].strftime("%B, %e %Y")} to #{@data[:period_ended_at].strftime("%B, %e %Y")}",@data[:invoice_total_payable_with_tax].format]
226
+ summary_data << ["#{@data[:period_started_at].strftime("%B, %e %Y")} to #{@data[:period_ended_at].strftime("%B, %e %Y")}",money(@data[:invoice_total_payable_with_tax])]
210
227
 
211
228
  # Draw Table background
212
229
  bg_height = @data[:invoice_tax_pips] > 0 ? 58 : 50
@@ -269,13 +286,13 @@ module MnoEnterprise
269
286
  @pdf.text_box "Credit Remaining", at: [445,@pdf.cursor], width: 95, height: 23, align: :center, valign: :center,
270
287
  style: :bold, size: 10
271
288
 
272
- @pdf.text_box @data[:customer_current_credit].format, at: [445,@pdf.cursor], width: 95, height: 37, align: :center, valign: :bottom
289
+ @pdf.text_box money(@data[:customer_current_credit]), at: [445,@pdf.cursor], width: 95, height: 37, align: :center, valign: :bottom
273
290
  end
274
291
 
275
292
  @pdf.move_down 40
276
293
  end
277
294
 
278
- #===============================
295
+ #========================()=======
279
296
  # Account Situation
280
297
  #===============================
281
298
  @pdf.move_down 30
@@ -304,15 +321,15 @@ module MnoEnterprise
304
321
  situation_data << [
305
322
  '',
306
323
  '',
307
- @data[:invoice_previous_total_due].format,
324
+ money(@data[:invoice_previous_total_due]),
308
325
  '-',
309
- @data[:invoice_previous_total_paid].format,
326
+ money(@data[:invoice_previous_total_paid]),
310
327
  '+',
311
- @data[:invoice_price].format,
328
+ money(@data[:invoice_price]),
312
329
  '-',
313
- @data[:invoice_credit_paid].format,
330
+ money(@data[:invoice_credit_paid]),
314
331
  '=',
315
- @data[:invoice_total_payable].format
332
+ money(@data[:invoice_total_payable])
316
333
  ]
317
334
 
318
335
  # Draw background
@@ -385,7 +402,7 @@ module MnoEnterprise
385
402
  '',
386
403
  'GST',
387
404
  '+',
388
- @data[:invoice_tax_payable].format,
405
+ money(@data[:invoice_tax_payable]),
389
406
  ]
390
407
 
391
408
  # Draw table background
@@ -442,7 +459,7 @@ module MnoEnterprise
442
459
  '',
443
460
  'Total (incl. GST)',
444
461
  '=',
445
- @data[:invoice_total_payable_with_tax].format,
462
+ money(@data[:invoice_total_payable_with_tax]),
446
463
  ]
447
464
 
448
465
  # Draw table background
@@ -0,0 +1,26 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
5
+ <%= stylesheet_link_tag('mno_enterprise/mail.css') %>
6
+ </head>
7
+ <body>
8
+ <p class="header">
9
+ <%= image_tag('mno_enterprise/main-logo.png') %>
10
+ </p>
11
+
12
+ <p>Hi <%= @info[:first_name] %></p>
13
+
14
+ <p>You can confirm your email by clicking on the following link</p>
15
+
16
+ <a href="<%= @info[:confirmation_link] %>">Confirm my account</a>
17
+
18
+ <p>
19
+ Regards,<br/>
20
+ The Marketplace team
21
+ </p>
22
+ <p class="footer">
23
+ <%= @info[:company] %>
24
+ </p>
25
+ </body>
26
+ </html>
@@ -0,0 +1,10 @@
1
+ Hi <%= @info[:first_name] %>
2
+ ==================================================================
3
+
4
+ You can confirm your email by clicking on the following link
5
+
6
+ To confirm your email, please follow this link : <%= @info[:confirmation_link] %>
7
+
8
+
9
+ Regards,
10
+ The Marketplace team
@@ -0,0 +1,31 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
5
+ <%= stylesheet_link_tag('mno_enterprise/mail.css') %>
6
+ </head>
7
+ <body>
8
+ <p class="header">
9
+ <%= image_tag('mno_enterprise/main-logo.png') %>
10
+ </p>
11
+
12
+ <p>Hi <%= @info[:first_name] %></p>
13
+
14
+ <p>We have received a request from you to terminate your account.</p>
15
+
16
+ <p>If this is a mistake, you can simply disregard this email - however, we strongly recommend you change your password too.</p>
17
+
18
+ <p>If you would like to proceed with the termination of your account you can do so by clicking the link below and following the prompts.</p>
19
+ <a href="<%= @info[:terminate_account_link] %>">Terminate Your Account</a>
20
+
21
+ <p>Please be advised, this is an irreversible action.</p>
22
+
23
+ <p>
24
+ Regards,<br/>
25
+ The Marketplace team
26
+ </p>
27
+ <p class="footer">
28
+ <%= @info[:company] %>
29
+ </p>
30
+ </body>
31
+ </html>
@@ -0,0 +1,15 @@
1
+ Hi <%= @info[:first_name] %>
2
+ =================================================================
3
+
4
+ We have received a request from you to terminate your account.
5
+
6
+ If this is a mistake, you can simply disregard this email - however, we strongly recommend you change your password too.
7
+
8
+ If you would like to proceed with the termination of your account you can do so by clicking the link below and following the prompts.
9
+ <%= @info[:terminate_account_link] %>
10
+
11
+ Please be advised, this is an irreversible action.
12
+
13
+
14
+ Regards,
15
+ The Marketplace team
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
5
+ <%= stylesheet_link_tag('mno_enterprise/mail.css') %>
6
+ </head>
7
+ <body>
8
+ <p class="header">
9
+ <%= image_tag('mno_enterprise/main-logo.png') %>
10
+ </p>
11
+
12
+ <p>Hi there,</p>
13
+
14
+ <p>You have been invited by <%= @info[:ref_full_name] %> to join <%= @info[:organization] %> on our platform!. You can automatically create your account on our platform and join <%= @info[:organization] %> by clicking on the link below:</p>
15
+ <a href="<%= @info[:confirmation_link] %>">Create my account and join <%= @info[:organization] %></a>
16
+
17
+ <% if @info[:team]? %>
18
+ <p>By accepting this invite you will automatically join the <%= @info[:team] %> team.</p>
19
+ <% end %>
20
+
21
+ <p>
22
+ Regards,<br/>
23
+ The Marketplace team
24
+ </p>
25
+
26
+ <p class="footer">
27
+ <%= @info[:company] %>
28
+ </p>
29
+ </body>
30
+ </html>
@@ -0,0 +1,13 @@
1
+ Hi there
2
+ =================================================================
3
+
4
+ You have been invited by <%= @info[:ref_full_name] %> to join <%= @info[:organization] %> on our platform!. You can automatically create your account on our platform and join <%= @info[:organization] %> by clicking on the link below:
5
+ <%= @info[:confirmation_link] %>
6
+
7
+ <% if @info[:team]? %>
8
+ By accepting this invite you will automatically join the <%= @info[:team] %> team.
9
+ <% end %>
10
+
11
+
12
+ Regards,
13
+ The Marketplace team
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
5
+ <%= stylesheet_link_tag('mno_enterprise/mail.css') %>
6
+ </head>
7
+ <body>
8
+ <p class="header">
9
+ <%= image_tag('mno_enterprise/main-logo.png') %>
10
+ </p>
11
+
12
+ <p>Hi there,</p>
13
+
14
+ <p>You have been invited by <%= @info[:ref_full_name] %> to join <%= @info[:organization] %> on our platform!. You can automatically create your account on our platform and join <%= @info[:organization] %> by clicking on the link below:</p>
15
+ <a href="<%= @info[:confirmation_link] %>">Create my account and join <%= @info[:organization] %></a>
16
+
17
+ <% if @info[:team]? %>
18
+ <p>By accepting this invite you will automatically join the <%= @info[:team] %> team.</p>
19
+ <% end %>
20
+
21
+ <p>
22
+ Regards,<br/>
23
+ The Marketplace team
24
+ </p>
25
+
26
+ <p class="footer">
27
+ <%= @info[:company] %>
28
+ </p>
29
+ </body>
30
+ </html>