mno-enterprise-core 2.0.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 +7 -0
- data/LICENSE +1 -0
- data/Rakefile +12 -0
- data/app/assets/images/mno_enterprise/main-logo.png +0 -0
- data/app/controllers/mno_enterprise/application_controller.rb +116 -0
- data/app/helpers/mno_enterprise/application_helper.rb +67 -0
- data/app/helpers/mno_enterprise/impersonate_helper.rb +27 -0
- data/app/models/mno_enterprise/ability.rb +6 -0
- data/app/models/mno_enterprise/app.rb +72 -0
- data/app/models/mno_enterprise/app_instance.rb +36 -0
- data/app/models/mno_enterprise/app_instances_sync.rb +6 -0
- data/app/models/mno_enterprise/arrears_situation.rb +6 -0
- data/app/models/mno_enterprise/audit_event.rb +21 -0
- data/app/models/mno_enterprise/base_resource.rb +228 -0
- data/app/models/mno_enterprise/credit_card.rb +40 -0
- data/app/models/mno_enterprise/deletion_request.rb +35 -0
- data/app/models/mno_enterprise/impac/dashboard.rb +36 -0
- data/app/models/mno_enterprise/impac/dashboard_provisioner.rb +5 -0
- data/app/models/mno_enterprise/impac/kpi.rb +9 -0
- data/app/models/mno_enterprise/impac/widget.rb +13 -0
- data/app/models/mno_enterprise/invoice.rb +53 -0
- data/app/models/mno_enterprise/org_invite.rb +50 -0
- data/app/models/mno_enterprise/organization.rb +33 -0
- data/app/models/mno_enterprise/team.rb +50 -0
- data/app/models/mno_enterprise/tenant.rb +5 -0
- data/app/models/mno_enterprise/tenant_invoice.rb +5 -0
- data/app/models/mno_enterprise/user.rb +183 -0
- data/app/pdf/mno_enterprise/invoice_pdf.rb +516 -0
- data/config/initializers/audit_log.rb +5 -0
- data/config/locales/devise.en.yml +60 -0
- data/config/routes.rb +2 -0
- data/config/styleguide.yml +106 -0
- data/lib/accountingjs_serializer.rb +51 -0
- data/lib/devise/controllers/extension_helpers.rb +52 -0
- data/lib/devise/extension_routes.rb +11 -0
- data/lib/devise/hooks/password_expirable.rb +5 -0
- data/lib/devise/models/password_expirable.rb +28 -0
- data/lib/devise/models/remote_authenticatable.rb +48 -0
- data/lib/devise/strategies/remote_authenticatable.rb +44 -0
- data/lib/devise_extension.rb +36 -0
- data/lib/faraday/adapter/net_http_no_proxy.rb +19 -0
- data/lib/generators/mno_enterprise/database_extension/USAGE +11 -0
- data/lib/generators/mno_enterprise/database_extension/database_extension_generator.rb +36 -0
- data/lib/generators/mno_enterprise/database_extension/templates/model.rb +9 -0
- data/lib/generators/mno_enterprise/dummy/dummy_generator.rb +98 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/application.rb.erb +9 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/boot.rb.erb +6 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/database.yml +22 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/routes.rb +8 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/test-env.rb +45 -0
- data/lib/generators/mno_enterprise/install/install_generator.rb +140 -0
- data/lib/generators/mno_enterprise/install/templates/Procfile +1 -0
- data/lib/generators/mno_enterprise/install/templates/config/initializers/mno_enterprise.rb +135 -0
- data/lib/generators/mno_enterprise/install/templates/config/mno_enterprise_styleguide.yml +104 -0
- data/lib/generators/mno_enterprise/install/templates/javascripts/mno_enterprise_extensions.js +7 -0
- data/lib/generators/mno_enterprise/install/templates/stylesheets/main.less_erb +25 -0
- data/lib/generators/mno_enterprise/install/templates/stylesheets/theme.less_erb +59 -0
- data/lib/generators/mno_enterprise/install/templates/stylesheets/variables.less +337 -0
- data/lib/generators/mno_enterprise/install/templates/tasks/sprites.rake +14 -0
- data/lib/generators/mno_enterprise/puma_stack/puma_stack_generator.rb +58 -0
- data/lib/generators/mno_enterprise/templates/scripts/monit/app-server.conf +8 -0
- data/lib/generators/mno_enterprise/templates/scripts/nginx/app +51 -0
- data/lib/generators/mno_enterprise/templates/scripts/puma.rb +25 -0
- data/lib/generators/mno_enterprise/templates/scripts/setup.sh +27 -0
- data/lib/generators/mno_enterprise/templates/scripts/upstart/app-web-hotrestart.conf +26 -0
- data/lib/generators/mno_enterprise/templates/scripts/upstart/app-web-server.conf +34 -0
- data/lib/generators/mno_enterprise/templates/scripts/upstart/app-web.conf +2 -0
- data/lib/generators/mno_enterprise/templates/scripts/upstart/app.conf +11 -0
- data/lib/her_extension/her_orm_adapter.rb +54 -0
- data/lib/her_extension/middleware/mnoe_api_v1_parse_json.rb +54 -0
- data/lib/her_extension/model/associations/association.rb +61 -0
- data/lib/her_extension/model/associations/association_proxy.rb +34 -0
- data/lib/her_extension/model/associations/has_many_association.rb +115 -0
- data/lib/her_extension/model/attributes.rb +43 -0
- data/lib/her_extension/model/orm.rb +59 -0
- data/lib/her_extension/model/parse.rb +40 -0
- data/lib/her_extension/model/relation.rb +92 -0
- data/lib/her_extension/validations/remote_uniqueness_validation.rb +33 -0
- data/lib/html_processor.rb +106 -0
- data/lib/mandrill_client.rb +58 -0
- data/lib/mno-enterprise-core.rb +1 -0
- data/lib/mno_enterprise/concerns.rb +4 -0
- data/lib/mno_enterprise/concerns/controllers.rb +6 -0
- data/lib/mno_enterprise/concerns/controllers/angular_csrf.rb +59 -0
- data/lib/mno_enterprise/concerns/controllers/auth.rb +9 -0
- data/lib/mno_enterprise/concerns/controllers/auth/confirmations_controller.rb +187 -0
- data/lib/mno_enterprise/concerns/controllers/auth/passwords_controller.rb +54 -0
- data/lib/mno_enterprise/concerns/controllers/auth/registrations_controller.rb +136 -0
- data/lib/mno_enterprise/concerns/controllers/auth/sessions_controller.rb +54 -0
- data/lib/mno_enterprise/concerns/controllers/auth/unlocks_controller.rb +50 -0
- data/lib/mno_enterprise/concerns/models.rb +6 -0
- data/lib/mno_enterprise/concerns/models/ability.rb +108 -0
- data/lib/mno_enterprise/concerns/models/app_instance.rb +100 -0
- data/lib/mno_enterprise/concerns/models/organization.rb +102 -0
- data/lib/mno_enterprise/core.rb +279 -0
- data/lib/mno_enterprise/database_extendable.rb +57 -0
- data/lib/mno_enterprise/engine.rb +33 -0
- data/lib/mno_enterprise/testing_support/ability_test_helper.rb +10 -0
- data/lib/mno_enterprise/testing_support/common_rake.rb +19 -0
- data/lib/mno_enterprise/testing_support/factories.rb +13 -0
- data/lib/mno_enterprise/testing_support/factories/app_instances.rb +30 -0
- data/lib/mno_enterprise/testing_support/factories/apps.rb +45 -0
- data/lib/mno_enterprise/testing_support/factories/arrears_situation.rb +14 -0
- data/lib/mno_enterprise/testing_support/factories/audit_event.rb +15 -0
- data/lib/mno_enterprise/testing_support/factories/credit_card.rb +33 -0
- data/lib/mno_enterprise/testing_support/factories/deletion_request.rb +17 -0
- data/lib/mno_enterprise/testing_support/factories/impac/dashboards.rb +15 -0
- data/lib/mno_enterprise/testing_support/factories/impac/kpis.rb +20 -0
- data/lib/mno_enterprise/testing_support/factories/impac/widgets.rb +15 -0
- data/lib/mno_enterprise/testing_support/factories/invoices.rb +51 -0
- data/lib/mno_enterprise/testing_support/factories/org_invite.rb +24 -0
- data/lib/mno_enterprise/testing_support/factories/organizations.rb +25 -0
- data/lib/mno_enterprise/testing_support/factories/team.rb +17 -0
- data/lib/mno_enterprise/testing_support/factories/tenant.rb +12 -0
- data/lib/mno_enterprise/testing_support/factories/tenant_invoice.rb +29 -0
- data/lib/mno_enterprise/testing_support/factories/users.rb +48 -0
- data/lib/mno_enterprise/testing_support/jpi_v1_test_helper.rb +49 -0
- data/lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb +167 -0
- data/lib/mno_enterprise/testing_support/mnoe_faraday_test_adapter.rb +173 -0
- data/lib/mno_enterprise/testing_support/organizations_shared_helpers.rb +175 -0
- data/lib/mno_enterprise/testing_support/user_action_shared.rb +47 -0
- data/lib/mno_enterprise/version.rb +3 -0
- data/lib/tasks/mno_enterprise_tasks.rake +22 -0
- data/spec/controllers/mno_enterprise/angular_csrf_spec.rb +42 -0
- data/spec/lib/her_extension/her_orm_adapter.rb +7 -0
- data/spec/lib/her_extension/model/relation_spec.rb +7 -0
- data/spec/lib/mandrill_client_spec.rb +64 -0
- data/spec/mno_enterprise_spec.rb +79 -0
- data/spec/models/mno_enterprise/app_instance_spec.rb +7 -0
- data/spec/models/mno_enterprise/app_spec.rb +62 -0
- data/spec/models/mno_enterprise/base_resource_spec.rb +28 -0
- data/spec/models/mno_enterprise/deletion_request_spec.rb +26 -0
- data/spec/models/mno_enterprise/invoice_spec.rb +7 -0
- data/spec/models/mno_enterprise/organization_spec.rb +7 -0
- data/spec/models/mno_enterprise/user_spec.rb +44 -0
- data/spec/rails_helper.rb +73 -0
- data/spec/spec_helper.rb +78 -0
- metadata +421 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module MnoEnterprise::Concerns::Controllers::Auth::SessionsController
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
#==================================================================
|
|
5
|
+
# Included methods
|
|
6
|
+
#==================================================================
|
|
7
|
+
# 'included do' causes the included code to be evaluated in the
|
|
8
|
+
# context where it is included rather than being executed in the module's context
|
|
9
|
+
included do
|
|
10
|
+
prepend_before_filter :capture_return_to_redirection
|
|
11
|
+
# before_filter :configure_sign_in_params, only: [:create]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
#==================================================================
|
|
15
|
+
# Class methods
|
|
16
|
+
#==================================================================
|
|
17
|
+
module ClassMethods
|
|
18
|
+
# def some_class_method
|
|
19
|
+
# 'some text'
|
|
20
|
+
# end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
#==================================================================
|
|
24
|
+
# Instance methods
|
|
25
|
+
#==================================================================
|
|
26
|
+
# GET /resource/sign_in
|
|
27
|
+
# def new
|
|
28
|
+
# super
|
|
29
|
+
# end
|
|
30
|
+
|
|
31
|
+
# POST /resource/sign_in
|
|
32
|
+
# def create
|
|
33
|
+
# super
|
|
34
|
+
# end
|
|
35
|
+
# def create
|
|
36
|
+
# self.resource = warden.authenticate!(auth_options)
|
|
37
|
+
# set_flash_message(:notice, :signed_in) if is_flashing_format?
|
|
38
|
+
# sign_in(resource_name, resource)
|
|
39
|
+
# yield resource if block_given?
|
|
40
|
+
# respond_with resource, location: after_sign_in_path_for(resource)
|
|
41
|
+
# end
|
|
42
|
+
|
|
43
|
+
# DELETE /resource/sign_out
|
|
44
|
+
# def destroy
|
|
45
|
+
# super
|
|
46
|
+
# end
|
|
47
|
+
|
|
48
|
+
# protected
|
|
49
|
+
|
|
50
|
+
# You can put the params you want to permit in the empty array.
|
|
51
|
+
# def configure_sign_in_params
|
|
52
|
+
# devise_parameter_sanitizer.for(:sign_in) << :attribute
|
|
53
|
+
# end
|
|
54
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
module MnoEnterprise::Concerns::Controllers::Auth::UnlocksController
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
#==================================================================
|
|
5
|
+
# Included methods
|
|
6
|
+
#==================================================================
|
|
7
|
+
# 'included do' causes the included code to be evaluated in the
|
|
8
|
+
# context where it is included rather than being executed in the module's context
|
|
9
|
+
included do
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
#==================================================================
|
|
13
|
+
# Class methods
|
|
14
|
+
#==================================================================
|
|
15
|
+
module ClassMethods
|
|
16
|
+
# def some_class_method
|
|
17
|
+
# 'some text'
|
|
18
|
+
# end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#==================================================================
|
|
22
|
+
# Instance methods
|
|
23
|
+
#==================================================================
|
|
24
|
+
# GET /resource/unlock/new
|
|
25
|
+
# def new
|
|
26
|
+
# super
|
|
27
|
+
# end
|
|
28
|
+
|
|
29
|
+
# POST /resource/unlock
|
|
30
|
+
# def create
|
|
31
|
+
# super
|
|
32
|
+
# end
|
|
33
|
+
|
|
34
|
+
# GET /resource/unlock?unlock_token=abcdef
|
|
35
|
+
# def show
|
|
36
|
+
# super
|
|
37
|
+
# end
|
|
38
|
+
|
|
39
|
+
# protected
|
|
40
|
+
|
|
41
|
+
# The path used after sending unlock password instructions
|
|
42
|
+
# def after_sending_unlock_instructions_path_for(resource)
|
|
43
|
+
# super(resource)
|
|
44
|
+
# end
|
|
45
|
+
|
|
46
|
+
# The path used after unlocking the resource
|
|
47
|
+
# def after_unlock_path_for(resource)
|
|
48
|
+
# super(resource)
|
|
49
|
+
# end
|
|
50
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
module MnoEnterprise::Concerns::Models::Ability
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
#==================================================================
|
|
5
|
+
# Included methods
|
|
6
|
+
#==================================================================
|
|
7
|
+
included do
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
#==================================================================
|
|
11
|
+
# Class methods
|
|
12
|
+
#==================================================================
|
|
13
|
+
module ClassMethods
|
|
14
|
+
# def some_class_method
|
|
15
|
+
# 'some text'
|
|
16
|
+
# end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#==================================================================
|
|
20
|
+
# Instance methods
|
|
21
|
+
#==================================================================
|
|
22
|
+
def initialize(user)
|
|
23
|
+
user ||= MnoEnterprise::User.new
|
|
24
|
+
|
|
25
|
+
#===================================================
|
|
26
|
+
# Organization
|
|
27
|
+
#===================================================
|
|
28
|
+
can :create, MnoEnterprise::Organization
|
|
29
|
+
|
|
30
|
+
can :read, MnoEnterprise::Organization do |organization|
|
|
31
|
+
!!user.role(organization)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
can [:update, :destroy, :manage_billing], MnoEnterprise::Organization do |organization|
|
|
35
|
+
user.role(organization) == 'Super Admin'
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
can [:upload,
|
|
39
|
+
:purchase,
|
|
40
|
+
:invite_member,
|
|
41
|
+
:administrate,
|
|
42
|
+
:manage_app_instances,
|
|
43
|
+
:manage_teams], MnoEnterprise::Organization do |organization|
|
|
44
|
+
['Super Admin','Admin'].include? user.role(organization)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# To be updated
|
|
48
|
+
can :sync_apps, MnoEnterprise::Organization do |organization|
|
|
49
|
+
user.role(organization)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# To be updated
|
|
53
|
+
can :check_apps_sync, MnoEnterprise::Organization do |organization|
|
|
54
|
+
user.role(organization)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#===================================================
|
|
58
|
+
# AppInstance
|
|
59
|
+
#===================================================
|
|
60
|
+
can :access, MnoEnterprise::AppInstance do |app_instance|
|
|
61
|
+
!!user.role(app_instance.owner) && (
|
|
62
|
+
['Super Admin','Admin'].include?(user.role(app_instance.owner)) ||
|
|
63
|
+
user.teams.empty? ||
|
|
64
|
+
user.teams.map(&:app_instances).compact.flatten.map(&:id).include?(app_instance.id)
|
|
65
|
+
)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
#===================================================
|
|
69
|
+
# Impac
|
|
70
|
+
#===================================================
|
|
71
|
+
impac_abilities(user)
|
|
72
|
+
|
|
73
|
+
# Define abilities for the passed in user here. For example:
|
|
74
|
+
#
|
|
75
|
+
# user ||= User.new # guest user (not logged in)
|
|
76
|
+
# if user.admin?
|
|
77
|
+
# can :manage, :all
|
|
78
|
+
# else
|
|
79
|
+
# can :read, :all
|
|
80
|
+
# end
|
|
81
|
+
#
|
|
82
|
+
# The first argument to `can` is the action you are giving the user
|
|
83
|
+
# permission to do.
|
|
84
|
+
# If you pass :manage it will apply to every action. Other common actions
|
|
85
|
+
# here are :read, :create, :update and :destroy.
|
|
86
|
+
#
|
|
87
|
+
# The second argument is the resource the user can perform the action on.
|
|
88
|
+
# If you pass :all it will apply to every resource. Otherwise pass a Ruby
|
|
89
|
+
# class of the resource.
|
|
90
|
+
#
|
|
91
|
+
# The third argument is an optional hash of conditions to further filter the
|
|
92
|
+
# objects.
|
|
93
|
+
# For example, here the user can only update published articles.
|
|
94
|
+
#
|
|
95
|
+
# can :update, Article, :published => true
|
|
96
|
+
#
|
|
97
|
+
# See the wiki for details:
|
|
98
|
+
# https://github.com/CanCanCommunity/cancancan/wiki/Defining-Abilities
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def impac_abilities(user)
|
|
102
|
+
can :manage_impac, MnoEnterprise::Impac::Dashboard do |dhb|
|
|
103
|
+
dhb.organizations.any? && dhb.organizations.all? do |org|
|
|
104
|
+
!!user.role(org) && ['Super Admin', 'Admin'].include?(user.role(org))
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# == Schema Information
|
|
2
|
+
#
|
|
3
|
+
# Endpoint:
|
|
4
|
+
# - /v1/app_instances
|
|
5
|
+
# - /v1/organizations/:organization_id/app_instances
|
|
6
|
+
#
|
|
7
|
+
# id :integer not null, primary key
|
|
8
|
+
# uid :string(255)
|
|
9
|
+
# name :string(255)
|
|
10
|
+
# status :string(255)
|
|
11
|
+
# app_id :integer
|
|
12
|
+
# created_at :datetime not null
|
|
13
|
+
# updated_at :datetime not null
|
|
14
|
+
# started_at :datetime
|
|
15
|
+
# stack :string(255)
|
|
16
|
+
# owner_id :integer
|
|
17
|
+
# owner_type :string(255)
|
|
18
|
+
# terminated_at :datetime
|
|
19
|
+
# stopped_at :datetime
|
|
20
|
+
# billing_type :string(255)
|
|
21
|
+
# autostop_at :datetime
|
|
22
|
+
# autostop_interval :integer
|
|
23
|
+
# next_status :string(255)
|
|
24
|
+
# soa_enabled :boolean default(FALSE)
|
|
25
|
+
#
|
|
26
|
+
# ===> to be confirmed
|
|
27
|
+
# http_url
|
|
28
|
+
# durations :text
|
|
29
|
+
# microsoft_licence_id :integer
|
|
30
|
+
#
|
|
31
|
+
|
|
32
|
+
module MnoEnterprise::Concerns::Models::AppInstance
|
|
33
|
+
extend ActiveSupport::Concern
|
|
34
|
+
|
|
35
|
+
#==================================================================
|
|
36
|
+
# Included methods
|
|
37
|
+
#==================================================================
|
|
38
|
+
# 'included do' causes the included code to be evaluated in the
|
|
39
|
+
# context where it is included rather than being executed in the module's context
|
|
40
|
+
included do
|
|
41
|
+
attributes :id, :uid, :name, :status, :app_id, :created_at, :updated_at, :started_at, :stack, :owner_id,
|
|
42
|
+
:owner_type, :terminated_at, :stopped_at, :billing_type, :autostop_at, :autostop_interval,
|
|
43
|
+
:next_status, :soa_enabled, :oauth_keys_valid, :oauth_company
|
|
44
|
+
|
|
45
|
+
#==============================================================
|
|
46
|
+
# Constants
|
|
47
|
+
#==============================================================
|
|
48
|
+
ACTIVE_STATUSES = [:running,:stopped,:staged,:provisioning,:starting,:stopping,:updating]
|
|
49
|
+
TERMINATION_STATUSES = [:terminating,:terminated]
|
|
50
|
+
|
|
51
|
+
#==============================================================
|
|
52
|
+
# Associations
|
|
53
|
+
#==============================================================
|
|
54
|
+
belongs_to :owner, class_name: 'MnoEnterprise::Organization'
|
|
55
|
+
belongs_to :app, class_name: 'MnoEnterprise::App'
|
|
56
|
+
|
|
57
|
+
# Define connector_stack?, cloud_stack? etc. methods
|
|
58
|
+
[:cube,:cloud,:connector].each do |stackname|
|
|
59
|
+
define_method("#{stackname}_stack?") do
|
|
60
|
+
self.stack == stackname.to_s
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
scope :active, -> { where('status.in' => ACTIVE_STATUSES) }
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#==================================================================
|
|
68
|
+
# Class methods
|
|
69
|
+
#==================================================================
|
|
70
|
+
module ClassMethods
|
|
71
|
+
# def some_class_method
|
|
72
|
+
# 'some text'
|
|
73
|
+
# end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#==================================================================
|
|
77
|
+
# Instance methods
|
|
78
|
+
#==================================================================
|
|
79
|
+
# Send a request to terminate the AppInstance
|
|
80
|
+
# Alias of destroy
|
|
81
|
+
# TODO: specs
|
|
82
|
+
def terminate
|
|
83
|
+
self.destroy
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Return true if the instance can be considered active
|
|
87
|
+
# Route53 DNS propagation may take up to a minute, so we force a minimum of 60 seconds before considering the application online
|
|
88
|
+
def active?
|
|
89
|
+
ACTIVE_STATUSES.include?(self.status.to_sym)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def running?
|
|
93
|
+
self.status == 'running'
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def online?
|
|
97
|
+
running? && [self.created_at, self.started_at].compact.max < 70.seconds.ago
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# == Schema Information
|
|
2
|
+
#
|
|
3
|
+
# Endpoint:
|
|
4
|
+
# - /v1/organizations
|
|
5
|
+
# - /v1/users/:user_id/organizations
|
|
6
|
+
#
|
|
7
|
+
# id :integer not null, primary key
|
|
8
|
+
# uid :string(255)
|
|
9
|
+
# name :string(255)
|
|
10
|
+
# created_at :datetime not null
|
|
11
|
+
# updated_at :datetime not null
|
|
12
|
+
# account_frozen :boolean default(FALSE)
|
|
13
|
+
# free_trial_end_at :datetime
|
|
14
|
+
# soa_enabled :boolean default(TRUE)
|
|
15
|
+
# mails :text
|
|
16
|
+
# logo :string(255)
|
|
17
|
+
# latitude :float default(0.0)
|
|
18
|
+
# longitude :float default(0.0)
|
|
19
|
+
# geo_country_code :string(255)
|
|
20
|
+
# geo_state_code :string(255)
|
|
21
|
+
# geo_city :string(255)
|
|
22
|
+
# geo_tz :string(255)
|
|
23
|
+
# geo_currency :string(255)
|
|
24
|
+
# meta_data :text
|
|
25
|
+
# industry :string(255)
|
|
26
|
+
# size :string(255)
|
|
27
|
+
#
|
|
28
|
+
|
|
29
|
+
module MnoEnterprise::Concerns::Models::Organization
|
|
30
|
+
extend ActiveSupport::Concern
|
|
31
|
+
|
|
32
|
+
#==================================================================
|
|
33
|
+
# Included methods
|
|
34
|
+
#==================================================================
|
|
35
|
+
# 'included do' causes the included code to be evaluated in the
|
|
36
|
+
# context where it is included rather than being executed in the module's context
|
|
37
|
+
included do
|
|
38
|
+
attributes :uid, :name, :account_frozen, :free_trial_end_at, :soa_enabled, :mails, :logo,
|
|
39
|
+
:latitude, :longitude, :geo_country_code, :geo_state_code, :geo_city, :geo_tz, :geo_currency,
|
|
40
|
+
:meta_data, :industry, :size
|
|
41
|
+
|
|
42
|
+
scope :in_arrears, -> { where(in_arrears?: true) }
|
|
43
|
+
|
|
44
|
+
#================================
|
|
45
|
+
# Associations
|
|
46
|
+
#================================
|
|
47
|
+
has_many :users, class_name: 'MnoEnterprise::User'
|
|
48
|
+
has_many :org_invites, class_name: 'MnoEnterprise::OrgInvite'
|
|
49
|
+
has_many :app_instances, class_name: 'MnoEnterprise::AppInstance'
|
|
50
|
+
has_many :invoices, class_name: 'MnoEnterprise::Invoice'
|
|
51
|
+
has_one :credit_card, class_name: 'MnoEnterprise::CreditCard'
|
|
52
|
+
has_many :teams, class_name: 'MnoEnterprise::Team'
|
|
53
|
+
has_many :dashboards, class_name: 'MnoEnterprise::Impac::Dashboard'
|
|
54
|
+
has_one :raw_last_invoice, class_name: 'MnoEnterprise::Invoice', path: '/last_invoice'
|
|
55
|
+
has_one :app_instances_sync, class_name: 'MnoEnterprise::AppInstancesSync'
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
#==================================================================
|
|
59
|
+
# Class methods
|
|
60
|
+
#==================================================================
|
|
61
|
+
module ClassMethods
|
|
62
|
+
# def some_class_method
|
|
63
|
+
# 'some text'
|
|
64
|
+
# end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#==================================================================
|
|
68
|
+
# Instance methods
|
|
69
|
+
#==================================================================
|
|
70
|
+
# Return the list of users + active invites
|
|
71
|
+
# TODO: specs
|
|
72
|
+
def members
|
|
73
|
+
[self.users,self.org_invites.active].flatten
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Add a user to the organization with the provided role
|
|
77
|
+
# TODO: specs
|
|
78
|
+
def add_user(user,role = 'Member')
|
|
79
|
+
self.users.create(id: user.id, role: role)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def last_invoice
|
|
83
|
+
inv = self.raw_last_invoice
|
|
84
|
+
inv.id ? inv : nil
|
|
85
|
+
end
|
|
86
|
+
# def last_invoice_with_nil
|
|
87
|
+
# last_invoice.respond_to?(:id) ? last_invoice : nil
|
|
88
|
+
# end
|
|
89
|
+
# alias_method_chain :last_invoice, :nil
|
|
90
|
+
|
|
91
|
+
# Remove a user from the organization
|
|
92
|
+
# TODO: specs
|
|
93
|
+
def remove_user(user)
|
|
94
|
+
self.users.destroy(id: user.id)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Change a user role in the organization
|
|
98
|
+
# TODO: specs
|
|
99
|
+
def update_user(user, role = 'Member')
|
|
100
|
+
self.users.update(id: user.id, role: role)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
require 'prawn'
|
|
2
|
+
require 'prawn/table'
|
|
3
|
+
require 'money'
|
|
4
|
+
require 'deepstruct'
|
|
5
|
+
require 'jwt'
|
|
6
|
+
require 'countries'
|
|
7
|
+
require 'cancancan'
|
|
8
|
+
require 'devise'
|
|
9
|
+
require 'devise/strategies/remote_authenticatable'
|
|
10
|
+
require 'devise_extension'
|
|
11
|
+
require "her"
|
|
12
|
+
require "her_extension/her_orm_adapter"
|
|
13
|
+
require "her_extension/model/orm"
|
|
14
|
+
require "her_extension/model/relation"
|
|
15
|
+
require "her_extension/model/attributes"
|
|
16
|
+
require "her_extension/model/parse"
|
|
17
|
+
require "her_extension/model/associations/association"
|
|
18
|
+
require "her_extension/model/associations/association_proxy"
|
|
19
|
+
require "her_extension/model/associations/has_many_association"
|
|
20
|
+
require "her_extension/middleware/mnoe_api_v1_parse_json"
|
|
21
|
+
require "faraday_middleware"
|
|
22
|
+
require "mno_enterprise/engine"
|
|
23
|
+
|
|
24
|
+
require 'mno_enterprise/database_extendable'
|
|
25
|
+
|
|
26
|
+
require 'mandrill'
|
|
27
|
+
require "mandrill_client"
|
|
28
|
+
|
|
29
|
+
require 'accountingjs_serializer'
|
|
30
|
+
|
|
31
|
+
module MnoEnterprise
|
|
32
|
+
|
|
33
|
+
#==================================================================
|
|
34
|
+
# MnoEnterprise Router
|
|
35
|
+
# Centralizes all URLs available on the Maestrano Enterprise side
|
|
36
|
+
#==================================================================
|
|
37
|
+
class Router
|
|
38
|
+
attr_accessor :terms_url
|
|
39
|
+
|
|
40
|
+
# Customise after_sign_out url
|
|
41
|
+
attr_accessor :after_sign_out_url
|
|
42
|
+
|
|
43
|
+
def terms_url
|
|
44
|
+
@terms_url || '#'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def launch_url(id,opts = {})
|
|
48
|
+
host_url("/launch/#{id}",opts)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def authorize_oauth_url(id,opts = {})
|
|
52
|
+
host_url("/oauth/#{id}/authorize",opts)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def disconnect_oauth_url(id,opts = {})
|
|
56
|
+
host_url("/oauth/#{id}/disconnect",opts)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def sync_oauth_url(id,opts = {})
|
|
60
|
+
host_url("/oauth/#{id}/sync",opts)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def impac_root_url
|
|
64
|
+
URI.join(MnoEnterprise.impac_api_host,MnoEnterprise.impac_api_root_path)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
def base_path
|
|
69
|
+
MnoEnterprise.mno_api_root_path
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def host
|
|
73
|
+
MnoEnterprise.mno_api_host
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def host_url(path,opts = {})
|
|
77
|
+
url = URI.join(host,"#{base_path}#{path}").to_s
|
|
78
|
+
url += "?#{opts.to_query}" if opts.any?
|
|
79
|
+
url
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
#==================================================================
|
|
84
|
+
# Module definition
|
|
85
|
+
#==================================================================
|
|
86
|
+
|
|
87
|
+
#====================================
|
|
88
|
+
# Tenant
|
|
89
|
+
#====================================
|
|
90
|
+
# Maestrano Enterprise Tenant name
|
|
91
|
+
mattr_accessor :app_name
|
|
92
|
+
@@tenant_name = 'Maestrano Enterprise'
|
|
93
|
+
|
|
94
|
+
# Maestrano Enterprise Default Country
|
|
95
|
+
mattr_accessor :app_country
|
|
96
|
+
@@app_country = 'US'
|
|
97
|
+
|
|
98
|
+
# Maestrano Enterprise Default Currency
|
|
99
|
+
mattr_accessor :app_currency
|
|
100
|
+
@@app_currency = 'USD'
|
|
101
|
+
|
|
102
|
+
# Maestrano Enterprise Tenant ID
|
|
103
|
+
mattr_accessor :tenant_id
|
|
104
|
+
@@tenant_id = nil
|
|
105
|
+
|
|
106
|
+
# Maestrano Enterprise Tenant Key
|
|
107
|
+
mattr_accessor :tenant_key
|
|
108
|
+
@@tenant_key = nil
|
|
109
|
+
|
|
110
|
+
#====================================
|
|
111
|
+
# Impac
|
|
112
|
+
#====================================
|
|
113
|
+
mattr_accessor :impac_api_host
|
|
114
|
+
@@impac_api_host = 'https://api-impac-uat.maestrano.io'
|
|
115
|
+
|
|
116
|
+
mattr_accessor :impac_api_root_path
|
|
117
|
+
@@impac_api_root_path = "/api/v1"
|
|
118
|
+
|
|
119
|
+
#====================================
|
|
120
|
+
# Enterprise API
|
|
121
|
+
#====================================
|
|
122
|
+
# The Maestrano Enterprise API Host
|
|
123
|
+
mattr_accessor :mno_api_host
|
|
124
|
+
@@mno_api_host = "https://api-enterprise.maestrano.com"
|
|
125
|
+
|
|
126
|
+
# The Maestrano Enterprise API Private Host
|
|
127
|
+
# Used within VPCs for making calls to mno_api using
|
|
128
|
+
# private DNS
|
|
129
|
+
mattr_accessor :mno_api_private_host
|
|
130
|
+
@@mno_api_private_host = nil
|
|
131
|
+
|
|
132
|
+
# The Maestrano Enterprise API base path
|
|
133
|
+
mattr_accessor :mno_api_root_path
|
|
134
|
+
@@mno_api_root_path = "/v1"
|
|
135
|
+
|
|
136
|
+
# Hold the Her API configuration (see configure_api method)
|
|
137
|
+
mattr_reader :mnoe_api_v1
|
|
138
|
+
@@mnoe_api_v1 = nil
|
|
139
|
+
|
|
140
|
+
# Hold the Maestrano enterprise router (redirection to central enterprise platform)
|
|
141
|
+
mattr_reader :router
|
|
142
|
+
@@router = Router.new
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
#====================================
|
|
146
|
+
# Emailing
|
|
147
|
+
#====================================
|
|
148
|
+
# Mandrill Key for sending emails
|
|
149
|
+
# Points to the default maestrano enterprise account
|
|
150
|
+
mattr_accessor :mandrill_key
|
|
151
|
+
@@mandrill_key = 'QcrLVdukhBi7iYrTeWHRPQ'
|
|
152
|
+
|
|
153
|
+
# The support email address
|
|
154
|
+
mattr_accessor :support_email
|
|
155
|
+
@@support_email = "support@example.com"
|
|
156
|
+
|
|
157
|
+
# Default sender name
|
|
158
|
+
mattr_accessor :default_sender_name
|
|
159
|
+
@@default_sender_name = nil
|
|
160
|
+
|
|
161
|
+
# Default sender email
|
|
162
|
+
mattr_accessor :default_sender_email
|
|
163
|
+
@@default_sender_email = "no-reply@example.com"
|
|
164
|
+
|
|
165
|
+
#===============================================
|
|
166
|
+
# Optional Modules
|
|
167
|
+
#===============================================
|
|
168
|
+
# Angular CSRF
|
|
169
|
+
mattr_accessor :include_angular_csrf
|
|
170
|
+
@@include_angular_csrf = false
|
|
171
|
+
|
|
172
|
+
#====================================
|
|
173
|
+
# Third Party Plugins
|
|
174
|
+
#====================================
|
|
175
|
+
mattr_accessor :google_tag_container
|
|
176
|
+
@@google_tag_container = nil
|
|
177
|
+
|
|
178
|
+
#====================================
|
|
179
|
+
# Layout & Styling
|
|
180
|
+
#====================================
|
|
181
|
+
# Nested structure defining the general style of the application
|
|
182
|
+
mattr_accessor :styleguide
|
|
183
|
+
mattr_accessor :style
|
|
184
|
+
@@styleguide = nil
|
|
185
|
+
@@style = nil
|
|
186
|
+
|
|
187
|
+
#====================================
|
|
188
|
+
# Marketplace
|
|
189
|
+
#====================================
|
|
190
|
+
# List of applications that should be offered on
|
|
191
|
+
# the marketplace
|
|
192
|
+
mattr_accessor :marketplace_listing
|
|
193
|
+
@@marketplace_listing = nil
|
|
194
|
+
|
|
195
|
+
#====================================
|
|
196
|
+
# Module Methods
|
|
197
|
+
#====================================
|
|
198
|
+
|
|
199
|
+
# Always reload style in development
|
|
200
|
+
def self.style
|
|
201
|
+
self.configure_styleguide if Rails.env.development?
|
|
202
|
+
@@style
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
# Default way to setup MnoEnterprise. Run rails generate mno-enterprise:install to create
|
|
206
|
+
# a fresh initializer with all configuration values.
|
|
207
|
+
def self.configure
|
|
208
|
+
yield self
|
|
209
|
+
self.configure_styleguide
|
|
210
|
+
self.configure_api
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Create a JSON web token with the provided payload
|
|
214
|
+
# E.g.: MnoEnterprise.jwt({ user_id: 'usr-427431' })
|
|
215
|
+
def self.jwt(payload)
|
|
216
|
+
secret = "#{self.tenant_id}:#{self.tenant_key}"
|
|
217
|
+
iat = Time.now.utc.to_i
|
|
218
|
+
|
|
219
|
+
JWT.encode(payload.merge(
|
|
220
|
+
iss: MnoEnterprise.tenant_id,
|
|
221
|
+
iat: iat,
|
|
222
|
+
jit: Digest::MD5.hexdigest("#{secret}:#{iat}")
|
|
223
|
+
), secret)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
private
|
|
227
|
+
# Return the options to use in the setup of the API
|
|
228
|
+
def self.api_options
|
|
229
|
+
api_host = @@mno_api_private_host || @@mno_api_host
|
|
230
|
+
{
|
|
231
|
+
url: "#{URI.join(api_host,@@mno_api_root_path).to_s}",
|
|
232
|
+
send_only_modified_attributes: true
|
|
233
|
+
}
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Load the provided styleguide hash into nested structure or load a default one
|
|
237
|
+
def self.configure_styleguide
|
|
238
|
+
# Load default gem configuration
|
|
239
|
+
hash = YAML.load(File.read(File.join(MnoEnterprise::Engine.root,'config','styleguide.yml')))
|
|
240
|
+
|
|
241
|
+
# Load default app styleguide, unless explicitly specified
|
|
242
|
+
default_path = File.join(Rails.root,'config','mno_enterprise_styleguide.yml')
|
|
243
|
+
if !@@styleguide && File.exists?(default_path)
|
|
244
|
+
@@styleguide = YAML.load(File.read(default_path))
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
@@styleguide.is_a?(Hash) && hash.deep_merge!(@@styleguide)
|
|
248
|
+
@@style = DeepStruct.wrap(hash)
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
# Configure the Her for Maestrano Enterprise API V1
|
|
252
|
+
def self.configure_api
|
|
253
|
+
# Configure HER for Maestrano Enterprise Endpoints
|
|
254
|
+
@@mnoe_api_v1 = Her::API.new
|
|
255
|
+
@@mnoe_api_v1.setup self.api_options do |c|
|
|
256
|
+
# Request
|
|
257
|
+
c.use Faraday::Request::BasicAuthentication, @@tenant_id, @@tenant_key
|
|
258
|
+
# c.use Faraday::Request::UrlEncoded
|
|
259
|
+
c.request :json
|
|
260
|
+
|
|
261
|
+
# Instrumentation in development
|
|
262
|
+
c.use :instrumentation if Rails.env.development?
|
|
263
|
+
|
|
264
|
+
# Response
|
|
265
|
+
c.use Her::Middleware::MnoeApiV1ParseJson
|
|
266
|
+
|
|
267
|
+
# Adapter
|
|
268
|
+
c.use Faraday::Adapter::NetHttpNoProxy
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
# Instrumentation in development
|
|
274
|
+
ActiveSupport::Notifications.subscribe('request.faraday') do |name, starts, ends, _, env|
|
|
275
|
+
url = env[:url]
|
|
276
|
+
http_method = env[:method].to_s.upcase
|
|
277
|
+
duration = ends - starts
|
|
278
|
+
Rails.logger.debug '[%s] %s %s (%.3f s)' % [url.host, http_method, url.request_uri, duration]
|
|
279
|
+
end if Rails.env.development?
|