mno-enterprise-core 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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?
|