mno-enterprise-core 3.3.2 → 3.3.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f917a6e753baa8624dce8b43b2bcb11fbcf2181e
4
- data.tar.gz: 65f316eaa0ffdc58c30b77fa277c5ab7a719b736
3
+ metadata.gz: a9bc8575caf93295002d64712d732d5fc882a09a
4
+ data.tar.gz: e27125cc924ba10ac4f62eecb668a1018a4717ad
5
5
  SHA512:
6
- metadata.gz: 3b7d6482aab8df033971214542cd4812f207c57d428d62501a20c2bffc529bb5b99d6a1ebc566e1ca7737e5bda6ba05b72d1530cb4b09dfdc55addb077613168
7
- data.tar.gz: 73a4607b1a631b6654fd83193880abce436ed050800d165497059ef5c32a3ef66fc5a9c71c923582be1685e83ab69a2777f99c354bcf831a2ddd48f0ab543c3e
6
+ metadata.gz: '0680225db073172cefab691f5bd89183d9f82858ff5fe3ad51760639109bde0f59563c7b241bdaf2100d89bd3479096e3371385aab09532e299985e6eeb7068f'
7
+ data.tar.gz: d5d82305dbe6d5c81290d99ce572694009cd7f2176e4edf275bd2deaa5ccb369a185163aeb76d9f61583ea6261c5ae277221b5e6ca52c936829f2ddad639d957
@@ -2,7 +2,6 @@ module MnoEnterprise
2
2
  class ApplicationController < ActionController::Base
3
3
  protect_from_forgery
4
4
  include ApplicationHelper
5
- prepend_before_filter :skip_devise_trackable_on_xhr
6
5
 
7
6
  before_filter :set_default_meta
8
7
  before_filter :store_location
@@ -19,6 +18,8 @@ module MnoEnterprise
19
18
  include MnoEnterprise::Concerns::Controllers::AngularCSRF
20
19
  end
21
20
 
21
+ rescue_from Faraday::ConnectionFailed, Faraday::TimeoutError, with: :handle_mnohub_error
22
+
22
23
  #============================================
23
24
  # CanCan Authorization Rescue
24
25
  #============================================
@@ -45,14 +46,10 @@ module MnoEnterprise
45
46
  #============================================
46
47
  protected
47
48
 
48
- # Do not updated devise last access timestamps on ajax call so that
49
- # timeout feature works properly
50
- # Only GET request get ignored - POST/PUT/DELETE requests reflect a
51
- # user action and should therefore be taken into account
52
- def skip_devise_trackable_on_xhr
53
- if request.format == 'application/json' && request.get?
54
- request.env["devise.skip_trackable"] = true
55
- end
49
+ # Do not update devise last access timestamps
50
+ # Used on XHR polling calls so that the timeout feature works properly
51
+ def skip_devise_trackable
52
+ request.env['devise.skip_trackable'] = true
56
53
  end
57
54
 
58
55
  # Return the user to the 'return_to' url if one was specified
@@ -138,5 +135,24 @@ module MnoEnterprise
138
135
  uri.fragment = fragment.to_s
139
136
  uri.to_s
140
137
  end
138
+
139
+ def handle_mnohub_error(exception)
140
+ @status = case exception
141
+ when Faraday::ConnectionFailed
142
+ 503 # :service_unavailable
143
+ when Faraday::TimeoutError
144
+ 429 # :too_many_requests
145
+ else
146
+ exception
147
+ end
148
+
149
+ respond_to do |format|
150
+ format.html do
151
+ @meta = {title: 'Backend unavailable'}
152
+ render 'error_page', layout: 'mno_enterprise/public', status: @status
153
+ end
154
+ format.json {render json: {error: 'API hub unavailable'}, status: @status}
155
+ end
156
+ end
141
157
  end
142
158
  end
@@ -61,7 +61,7 @@ module MnoEnterprise
61
61
  # Sanitize the app description
62
62
  # E.g.: replace any mention of Maestrano by the tenant name
63
63
  def sanitized_description
64
- @sanitized_description ||= (self.description || '').gsub(/(?!cdn\.)maestrano(?!\.com)/i,MnoEnterprise.app_name)
64
+ @sanitized_description ||= (self.description || '').gsub(/(?<!cdn\.)(?<!cdn-prd-)maestrano(?!\.com)/i,MnoEnterprise.app_name)
65
65
  end
66
66
 
67
67
  # Methods for appinfo flags
@@ -51,7 +51,7 @@ module MnoEnterprise
51
51
  :last_sign_in_ip, :confirmation_token, :confirmed_at, :confirmation_sent_at, :unconfirmed_email,
52
52
  :failed_attempts, :unlock_token, :locked_at, :name, :surname, :company, :phone, :phone_country_code,
53
53
  :geo_country_code, :geo_state_code, :geo_city, :website, :orga_on_create, :sso_session, :current_password_required, :admin_role,
54
- :api_key, :api_secret, :developer, :kpi_enabled, :external_id, :meta_data
54
+ :api_key, :api_secret, :developer, :kpi_enabled, :external_id, :meta_data, :password_valid
55
55
 
56
56
  define_model_callbacks :validation #required by Devise
57
57
 
@@ -94,14 +94,14 @@ module MnoEnterprise
94
94
  # The auth_hash includes an email and password
95
95
  # Return nil in case of failure
96
96
  def self.authenticate(auth_hash)
97
- u = self.post("user_sessions", auth_hash)
98
-
97
+ # retro compatibilty issue: previous version were returning nil if the user was not found or if the password was invalid
98
+ # see https://maestrano.atlassian.net/browse/MNOE-209
99
+ # we now validate that the password is valid in /core/lib/devise/strategies/remote_authenticatable.rb
100
+ u = self.post("user_sessions", auth_hash.merge(validate_password: true))
99
101
  if u && u.id
100
102
  u.clear_attribute_changes!
101
- return u
102
103
  end
103
-
104
- nil
104
+ return u
105
105
  end
106
106
 
107
107
 
@@ -0,0 +1,29 @@
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(main_logo_white_bg_path, style: fit_image) %>
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!</p>
15
+
16
+ <% if @info[:team] %>
17
+ <p>You have been added to the <%= @info[:team] %> team.</p>
18
+ <% end %>
19
+
20
+ <p>
21
+ Regards,<br/>
22
+ The Marketplace team
23
+ </p>
24
+
25
+ <p class="footer">
26
+ <%= @info[:company] %>
27
+ </p>
28
+ </body>
29
+ </html>
@@ -0,0 +1,12 @@
1
+ Hi there
2
+ =================================================================
3
+
4
+ You have been invited by <%= @info[:ref_full_name] %> to join <%= @info[:organization] %> on our platform!
5
+
6
+ <% if @info[:team] %>
7
+ You have been added to the <%= @info[:team] %> team.
8
+ <% end %>
9
+
10
+
11
+ Regards,
12
+ The Marketplace team
@@ -62,7 +62,7 @@ en:
62
62
  current_password: 'Current Password'
63
63
  new_password: 'New Password'
64
64
  confirm_password: 'Confirm Password'
65
- eight_characters_minimum: 'Eight characters minimum'
65
+ minimum_length: '{length} characters minimum'
66
66
  one_uppercase_character: 'One uppercase character'
67
67
  one_number: 'One number'
68
68
  one_lowercase_character: 'One lowercase character'
@@ -37,7 +37,7 @@ en:
37
37
  platform_admin: "Platform moderator"
38
38
  edited_by_user: "Edited by User"
39
39
  edited_by_user_tooltip: "Show edit history"
40
- edited_by_admin: "Edited by Admin"
40
+ edited_by_admin: "Edited by Platform moderator"
41
41
  just_now: "Just Now"
42
42
  company_feedback: "Company feedback"
43
43
  review_title: "Review"
@@ -25,6 +25,8 @@ en:
25
25
  search: "Search"
26
26
  categories: "Categories"
27
27
  max_apps_selected: "You cannot start with more than 4 apps, you will be able to add more at a later stage."
28
+ max_apps_selected_tooltip: "You can only select 4 applications at a time, please remove one application before adding a new one"
29
+ conflicting_app_selected_tooltip: "You cannot install this App as it is incompatible with: {appName}"
28
30
  data_sync:
29
31
  what_data: "What data will be synchronised"
30
32
  start: "Visualise what data will be synchronised from your applications by clicking on their icons."
@@ -5,3 +5,11 @@ en:
5
5
  new:
6
6
  title: Sign In
7
7
  sign_in: Sign in
8
+ timeout: You are logged off due to inactivity. Please log in again
9
+ timeout:
10
+ header: "Session Timeout"
11
+ body:
12
+ can_login: "Your session has expired due to inactivity. You can extend your session or log out by clicking on the relevant option below"
13
+ stay_logged_in: "Stay Logged In"
14
+ log_off: "Log Off"
15
+ error: "We could not manage to remain you logged in. You will be redirected to the login page"
@@ -0,0 +1,13 @@
1
+ en:
2
+ mno_enterprise:
3
+ errors:
4
+ "503":
5
+ title: "Looks like we're having some server issues."
6
+ description: "We will redirect you as soon as it's online. Otherwise try again in a moment."
7
+ "500":
8
+ title: "Looks like we're having some server issues."
9
+ description: "If the problem persists, please contact support at %{support_email}."
10
+ "429":
11
+ title: "Too many requests."
12
+ description: "We are receiving too many requests. Please try again in a moment."
13
+ redirection: "Go to Homepage"
@@ -31,7 +31,7 @@ module DeviseExtension
31
31
 
32
32
  # redirect for password update with alert message
33
33
  def redirect_for_password_change(scope)
34
- redirect_to change_password_required_path_for(scope), :alert => 'Your password is expired. Please renew your password.'
34
+ redirect_to change_password_required_path_for(scope), alert: 'Your password has expired. Please renew your password.'
35
35
  end
36
36
 
37
37
  # path for change password
@@ -1,19 +1,20 @@
1
1
  module Devise
2
2
  module Strategies
3
3
  class RemoteAuthenticatable < Authenticatable
4
-
4
+
5
5
  # def valid?
6
6
  # true || params[scope]
7
7
  # end
8
-
8
+
9
9
  # For an example check : https://github.com/plataformatec/devise/blob/master/lib/devise/strategies/database_authenticatable.rb
10
10
  # Method called by warden to authenticate a resource.
11
11
  def authenticate!
12
12
  # authentication_hash doesn't include the password
13
13
  auth_params = params[scope]
14
-
14
+
15
+
15
16
  # mapping.to is a wrapper over the resource model
16
- resource = mapping.to.new
17
+ resource = mapping.to.new.remote_authentication(auth_params)
17
18
 
18
19
  return fail! unless resource
19
20
 
@@ -24,7 +25,7 @@ module Devise
24
25
  #
25
26
  # If the block returns true the resource will be loged in
26
27
  # If the block returns false the authentication will fail!
27
- if validate(resource){ resource = resource.remote_authentication(auth_params) }
28
+ if validate(resource) { resource.password_valid }
28
29
  success!(resource)
29
30
  end
30
31
  end
@@ -35,10 +36,10 @@ end
35
36
  Warden::Strategies.add :remote_authenticatable, Devise::Strategies::RemoteAuthenticatable
36
37
  Devise.add_module :remote_authenticatable, strategy: true, controller: :sessions, route: :session
37
38
 
38
- Warden::Manager.after_authentication do |user,auth,opts|
39
+ Warden::Manager.after_authentication do |user, auth, opts|
39
40
  Rails.cache.delete(['user', user.to_key]) if user
40
41
  end
41
42
 
42
- Warden::Manager.before_logout do |user,auth,opts|
43
+ Warden::Manager.before_logout do |user, auth, opts|
43
44
  Rails.cache.delete(['user', user.to_key]) if user
44
45
  end
@@ -16,6 +16,7 @@ FactoryGirl.define do
16
16
 
17
17
  created_at 1.days.ago
18
18
  updated_at 1.hour.ago
19
+ notification_sent_at 1.hour.ago
19
20
 
20
21
  # Properly build the resource with Her
21
22
  initialize_with { new(attributes).tap { |e| e.clear_attribute_changes! } }
@@ -0,0 +1,20 @@
1
+ # Helpers used in Request Specs
2
+ module MnoEnterprise::TestingSupport::RequestSpecHelper
3
+ shared_context 'signed in user' do
4
+ # Simulate a user login by login through devise
5
+ def login
6
+ # Stub user manipulation
7
+ api_stub_for(get: "/users/#{user.id}", response: from_api(user))
8
+ api_stub_for(put: "/users/#{user.id}", response: from_api(user))
9
+
10
+ # Stub session authentication
11
+ api_stub_for(post: '/user_sessions', code: 200, response: from_api(user))
12
+
13
+ # Log in
14
+ post '/mnoe/auth/users/sign_in', user: {email: user.email, password: 'securepassword'}
15
+ end
16
+
17
+ let(:user) { FactoryGirl.build(:user, password_valid: true) }
18
+ before { login }
19
+ end
20
+ end
@@ -1,3 +1,3 @@
1
1
  module MnoEnterprise
2
- VERSION = '3.3.2'
2
+ VERSION = '3.3.3'
3
3
  end
@@ -27,5 +27,43 @@ module MnoEnterprise
27
27
  it { expect(controller.after_sign_in_path_for(User.new(admin_role: ""))).to eq('/dashboard/') }
28
28
  it { expect(controller.after_sign_in_path_for(User.new(admin_role: "admin"))).to eq('/admin/') }
29
29
  end
30
+
31
+ describe 'Error Handling' do
32
+ subject { get :index, format: :json }
33
+
34
+ context 'ConnectionFailed' do
35
+ controller(MnoEnterprise::ApplicationController) do
36
+ skip_before_filter :perform_return_to, only: [:index]
37
+
38
+ def index
39
+ raise Faraday::ConnectionFailed, nil
40
+ end
41
+
42
+ def handle_mnohub_error(exception)
43
+ super
44
+ end
45
+ end
46
+
47
+ subject { get :index, format: :json }
48
+
49
+ it { is_expected.to have_http_status(:service_unavailable) }
50
+ end
51
+
52
+ context 'TimeoutError' do
53
+ controller(MnoEnterprise::ApplicationController) do
54
+ skip_before_filter :perform_return_to, only: [:index]
55
+
56
+ def index
57
+ raise Faraday::TimeoutError, nil
58
+ end
59
+
60
+ def handle_mnohub_error(exception)
61
+ super
62
+ end
63
+ end
64
+
65
+ it { is_expected.to have_http_status(:too_many_requests) }
66
+ end
67
+ end
30
68
  end
31
69
  end
@@ -41,6 +41,11 @@ module MnoEnterprise
41
41
  app.description = 'Screenshot: <img src="//cdn.maestrano.com/web/mno/screenshot.png"/>'
42
42
  expect(app.sanitized_description).to eq(app.description)
43
43
  end
44
+
45
+ it 'does not replace for bucket name cdn-prd-maestrano' do
46
+ app.description = '<a href="https://s3.amazonaws.com/cdn-prd-maestrano/somefile" target="_blank">report</a>'
47
+ expect(app.sanitized_description).to eq(app.description)
48
+ end
44
49
  end
45
50
 
46
51
  describe '#regenerate_api_key!' do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mno-enterprise-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.2
4
+ version: 3.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arnaud Lachaume
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-11-09 00:00:00.000000000 Z
12
+ date: 2018-10-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -369,6 +369,8 @@ files:
369
369
  - app/views/system_notifications/organization-invite-existing-user.text.erb
370
370
  - app/views/system_notifications/organization-invite-new-user.html.erb
371
371
  - app/views/system_notifications/organization-invite-new-user.text.erb
372
+ - app/views/system_notifications/organization-invite-notification.html.erb
373
+ - app/views/system_notifications/organization-invite-notification.text.erb
372
374
  - app/views/system_notifications/password-change.html.erb
373
375
  - app/views/system_notifications/password-change.text.erb
374
376
  - app/views/system_notifications/reconfirmation-instructions.html.erb
@@ -468,6 +470,7 @@ files:
468
470
  - config/locales/views/auth/unlocks/en.yml
469
471
  - config/locales/views/auth/unlocks/id.yml
470
472
  - config/locales/views/auth/unlocks/zh.yml
473
+ - config/locales/views/errors/en.yml
471
474
  - config/locales/views/pages/en.yml
472
475
  - config/locales/views/pages/id.yml
473
476
  - config/locales/views/pages/zh.yml
@@ -600,6 +603,7 @@ files:
600
603
  - lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb
601
604
  - lib/mno_enterprise/testing_support/mnoe_faraday_test_adapter.rb
602
605
  - lib/mno_enterprise/testing_support/organizations_shared_helpers.rb
606
+ - lib/mno_enterprise/testing_support/request_spec_helper.rb
603
607
  - lib/mno_enterprise/testing_support/shared_contexts/rake_task.rb
604
608
  - lib/mno_enterprise/testing_support/shared_examples/jpi_v1_admin.rb
605
609
  - lib/mno_enterprise/testing_support/user_action_shared.rb
@@ -657,7 +661,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
657
661
  version: '0'
658
662
  requirements: []
659
663
  rubyforge_project:
660
- rubygems_version: 2.6.8
664
+ rubygems_version: 2.6.14
661
665
  signing_key:
662
666
  specification_version: 4
663
667
  summary: Maestrano Enterprise - Core functionnality