mno-enterprise-core 3.3.2 → 3.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/controllers/mno_enterprise/application_controller.rb +25 -9
- data/app/models/mno_enterprise/app.rb +1 -1
- data/app/models/mno_enterprise/user.rb +6 -6
- data/app/views/system_notifications/organization-invite-notification.html.erb +29 -0
- data/app/views/system_notifications/organization-invite-notification.text.erb +12 -0
- data/config/locales/templates/components/en.yml +1 -1
- data/config/locales/templates/dashboard/marketplace/en.yml +1 -1
- data/config/locales/templates/onboarding/en.yml +2 -0
- data/config/locales/views/auth/sessions/en.yml +8 -0
- data/config/locales/views/errors/en.yml +13 -0
- data/lib/devise/controllers/extension_helpers.rb +1 -1
- data/lib/devise/strategies/remote_authenticatable.rb +8 -7
- data/lib/mno_enterprise/testing_support/factories/org_invite.rb +1 -0
- data/lib/mno_enterprise/testing_support/request_spec_helper.rb +20 -0
- data/lib/mno_enterprise/version.rb +1 -1
- data/spec/controllers/mno_enterprise/application_controller_spec.rb +38 -0
- data/spec/models/mno_enterprise/app_spec.rb +5 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a9bc8575caf93295002d64712d732d5fc882a09a
|
4
|
+
data.tar.gz: e27125cc924ba10ac4f62eecb668a1018a4717ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
49
|
-
# timeout feature works properly
|
50
|
-
|
51
|
-
|
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(/(
|
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
|
-
|
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
|
-
|
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
|
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), :
|
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
|
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
|
@@ -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
|
@@ -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.
|
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:
|
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.
|
664
|
+
rubygems_version: 2.6.14
|
661
665
|
signing_key:
|
662
666
|
specification_version: 4
|
663
667
|
summary: Maestrano Enterprise - Core functionnality
|