mno-enterprise-api 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.
Files changed (208) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +1 -0
  3. data/Rakefile +12 -0
  4. data/app/assets/javascripts/mno_enterprise/angular/loading-page.app.js.coffee +156 -0
  5. data/app/assets/javascripts/mno_enterprise/application.js +13 -0
  6. data/app/controllers/devise/password_expired_controller.rb +55 -0
  7. data/app/controllers/mno_enterprise/auth/confirmations_controller.rb +5 -0
  8. data/app/controllers/mno_enterprise/auth/omniauth_callbacks_controller.rb +30 -0
  9. data/app/controllers/mno_enterprise/auth/passwords_controller.rb +5 -0
  10. data/app/controllers/mno_enterprise/auth/registrations_controller.rb +5 -0
  11. data/app/controllers/mno_enterprise/auth/sessions_controller.rb +7 -0
  12. data/app/controllers/mno_enterprise/auth/unlocks_controller.rb +5 -0
  13. data/app/controllers/mno_enterprise/deletion_requests_controller.rb +5 -0
  14. data/app/controllers/mno_enterprise/impersonate_controller.rb +48 -0
  15. data/app/controllers/mno_enterprise/jpi/v1/admin/audit_events_controller.rb +16 -0
  16. data/app/controllers/mno_enterprise/jpi/v1/admin/base_resource_controller.rb +5 -0
  17. data/app/controllers/mno_enterprise/jpi/v1/admin/cloud_apps_controller.rb +46 -0
  18. data/app/controllers/mno_enterprise/jpi/v1/admin/invoices_controller.rb +47 -0
  19. data/app/controllers/mno_enterprise/jpi/v1/admin/organizations_controller.rb +27 -0
  20. data/app/controllers/mno_enterprise/jpi/v1/admin/tenant_invoices_controller.rb +14 -0
  21. data/app/controllers/mno_enterprise/jpi/v1/admin/users_controller.rb +63 -0
  22. data/app/controllers/mno_enterprise/jpi/v1/app_instances_controller.rb +24 -0
  23. data/app/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller.rb +36 -0
  24. data/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb +32 -0
  25. data/app/controllers/mno_enterprise/jpi/v1/current_users_controller.rb +5 -0
  26. data/app/controllers/mno_enterprise/jpi/v1/deletion_requests_controller.rb +5 -0
  27. data/app/controllers/mno_enterprise/jpi/v1/impac/dashboards_controller.rb +5 -0
  28. data/app/controllers/mno_enterprise/jpi/v1/impac/kpis_controller.rb +80 -0
  29. data/app/controllers/mno_enterprise/jpi/v1/impac/widgets_controller.rb +63 -0
  30. data/app/controllers/mno_enterprise/jpi/v1/industry_bundle_controller.rb +25 -0
  31. data/app/controllers/mno_enterprise/jpi/v1/marketplace_controller.rb +22 -0
  32. data/app/controllers/mno_enterprise/jpi/v1/organizations_controller.rb +5 -0
  33. data/app/controllers/mno_enterprise/jpi/v1/shopping_cart_controller.rb +93 -0
  34. data/app/controllers/mno_enterprise/jpi/v1/teams_controller.rb +88 -0
  35. data/app/controllers/mno_enterprise/org_invites_controller.rb +5 -0
  36. data/app/controllers/mno_enterprise/pages_controller.rb +5 -0
  37. data/app/controllers/mno_enterprise/provision_controller.rb +5 -0
  38. data/app/controllers/mno_enterprise/status_controller.rb +27 -0
  39. data/app/controllers/mno_enterprise/webhook/o_auth_controller.rb +5 -0
  40. data/app/mailers/mno_enterprise/system_notification_mailer.rb +5 -0
  41. data/app/models/mno_enterprise/health_check.rb +16 -0
  42. data/app/views/devise/password_expired/show.html.haml +32 -0
  43. data/app/views/mno_enterprise/auth/confirmations/default/_form.html.haml +49 -0
  44. data/app/views/mno_enterprise/auth/confirmations/default/_lounge.html.haml +34 -0
  45. data/app/views/mno_enterprise/auth/confirmations/default/_show.html.haml +10 -0
  46. data/app/views/mno_enterprise/auth/confirmations/lounge.html.haml +4 -0
  47. data/app/views/mno_enterprise/auth/confirmations/material/_form.html.haml +44 -0
  48. data/app/views/mno_enterprise/auth/confirmations/material/_lounge.html.haml +18 -0
  49. data/app/views/mno_enterprise/auth/confirmations/material/_show.html.haml +21 -0
  50. data/app/views/mno_enterprise/auth/confirmations/new.html.haml +31 -0
  51. data/app/views/mno_enterprise/auth/confirmations/show.html.haml +4 -0
  52. data/app/views/mno_enterprise/auth/mailer/confirmation_instructions.html.haml +4 -0
  53. data/app/views/mno_enterprise/auth/mailer/reset_password_instructions.html.haml +6 -0
  54. data/app/views/mno_enterprise/auth/mailer/unlock_instructions.html.haml +5 -0
  55. data/app/views/mno_enterprise/auth/passwords/edit.html.haml +53 -0
  56. data/app/views/mno_enterprise/auth/passwords/new.html.haml +34 -0
  57. data/app/views/mno_enterprise/auth/registrations/default/_form.html.haml +35 -0
  58. data/app/views/mno_enterprise/auth/registrations/default/_new.html.haml +11 -0
  59. data/app/views/mno_enterprise/auth/registrations/material/_form.html.haml +30 -0
  60. data/app/views/mno_enterprise/auth/registrations/material/_new.html.haml +10 -0
  61. data/app/views/mno_enterprise/auth/registrations/new.html.haml +4 -0
  62. data/app/views/mno_enterprise/auth/sessions/default/_form.html.haml +17 -0
  63. data/app/views/mno_enterprise/auth/sessions/default/_new.html.haml +11 -0
  64. data/app/views/mno_enterprise/auth/sessions/material/_form.html.haml +26 -0
  65. data/app/views/mno_enterprise/auth/sessions/material/_new.html.haml +11 -0
  66. data/app/views/mno_enterprise/auth/sessions/new.html.haml +4 -0
  67. data/app/views/mno_enterprise/auth/shared/_links.html.haml +24 -0
  68. data/app/views/mno_enterprise/auth/unlocks/new.html.haml +10 -0
  69. data/app/views/mno_enterprise/deletion_requests/show.html.haml +131 -0
  70. data/app/views/mno_enterprise/jpi/v1/admin/audit_events/_audit_event.json.jbuilder +5 -0
  71. data/app/views/mno_enterprise/jpi/v1/admin/audit_events/index.json.jbuilder +4 -0
  72. data/app/views/mno_enterprise/jpi/v1/admin/cloud_apps/_cloud_app.json.jbuilder +1 -0
  73. data/app/views/mno_enterprise/jpi/v1/admin/cloud_apps/index.json.jbuilder +1 -0
  74. data/app/views/mno_enterprise/jpi/v1/admin/cloud_apps/show.json.jbuilder +1 -0
  75. data/app/views/mno_enterprise/jpi/v1/admin/invoices/_invoice.json.jbuilder +2 -0
  76. data/app/views/mno_enterprise/jpi/v1/admin/invoices/index.json.jbuilder +1 -0
  77. data/app/views/mno_enterprise/jpi/v1/admin/invoices/show.json.jbuilder +2 -0
  78. data/app/views/mno_enterprise/jpi/v1/admin/organizations/_credit_card.json.jbuilder +7 -0
  79. data/app/views/mno_enterprise/jpi/v1/admin/organizations/_invoices.json.jbuilder +8 -0
  80. data/app/views/mno_enterprise/jpi/v1/admin/organizations/_member.json.jbuilder +14 -0
  81. data/app/views/mno_enterprise/jpi/v1/admin/organizations/_organization.json.jbuilder +1 -0
  82. data/app/views/mno_enterprise/jpi/v1/admin/organizations/in_arrears.json.jbuilder +8 -0
  83. data/app/views/mno_enterprise/jpi/v1/admin/organizations/index.json.jbuilder +7 -0
  84. data/app/views/mno_enterprise/jpi/v1/admin/organizations/show.json.jbuilder +11 -0
  85. data/app/views/mno_enterprise/jpi/v1/admin/tenant_invoices/_tenant_invoice.json.jbuilder +5 -0
  86. data/app/views/mno_enterprise/jpi/v1/admin/tenant_invoices/index.json.jbuilder +1 -0
  87. data/app/views/mno_enterprise/jpi/v1/admin/tenant_invoices/show.json.jbuilder +1 -0
  88. data/app/views/mno_enterprise/jpi/v1/admin/users/_user.json.jbuilder +1 -0
  89. data/app/views/mno_enterprise/jpi/v1/admin/users/index.json.jbuilder +2 -0
  90. data/app/views/mno_enterprise/jpi/v1/admin/users/show.json.jbuilder +9 -0
  91. data/app/views/mno_enterprise/jpi/v1/app_instances/_resource.json.jbuilder +23 -0
  92. data/app/views/mno_enterprise/jpi/v1/app_instances/index.json.jbuilder +9 -0
  93. data/app/views/mno_enterprise/jpi/v1/app_instances/show.json.jbuilder +3 -0
  94. data/app/views/mno_enterprise/jpi/v1/billing/index.json.jbuilder +0 -0
  95. data/app/views/mno_enterprise/jpi/v1/current_users/show.json.jbuilder +37 -0
  96. data/app/views/mno_enterprise/jpi/v1/impac/dashboards/_dashboard.json.jbuilder +9 -0
  97. data/app/views/mno_enterprise/jpi/v1/impac/dashboards/index.json.jbuilder +1 -0
  98. data/app/views/mno_enterprise/jpi/v1/impac/dashboards/show.json.jbuilder +1 -0
  99. data/app/views/mno_enterprise/jpi/v1/impac/kpis/_kpi.json.jbuilder +1 -0
  100. data/app/views/mno_enterprise/jpi/v1/impac/kpis/show.json.jbuilder +1 -0
  101. data/app/views/mno_enterprise/jpi/v1/impac/widgets/_widget.json.jbuilder +6 -0
  102. data/app/views/mno_enterprise/jpi/v1/impac/widgets/show.json.jbuilder +1 -0
  103. data/app/views/mno_enterprise/jpi/v1/marketplace/_app.json.jbuilder +14 -0
  104. data/app/views/mno_enterprise/jpi/v1/marketplace/index.json.jbuilder +3 -0
  105. data/app/views/mno_enterprise/jpi/v1/marketplace/show.json.jbuilder +3 -0
  106. data/app/views/mno_enterprise/jpi/v1/organizations/_arrears.json.jbuilder +11 -0
  107. data/app/views/mno_enterprise/jpi/v1/organizations/_billing.json.jbuilder +4 -0
  108. data/app/views/mno_enterprise/jpi/v1/organizations/_credit_card.json.jbuilder +7 -0
  109. data/app/views/mno_enterprise/jpi/v1/organizations/_current_user.json.jbuilder +5 -0
  110. data/app/views/mno_enterprise/jpi/v1/organizations/_invoices.json.jbuilder +8 -0
  111. data/app/views/mno_enterprise/jpi/v1/organizations/_member.json.jbuilder +13 -0
  112. data/app/views/mno_enterprise/jpi/v1/organizations/_organization.json.jbuilder +13 -0
  113. data/app/views/mno_enterprise/jpi/v1/organizations/credit_card.json.jbuilder +1 -0
  114. data/app/views/mno_enterprise/jpi/v1/organizations/index.json.jbuilder +1 -0
  115. data/app/views/mno_enterprise/jpi/v1/organizations/members.json.jbuilder +3 -0
  116. data/app/views/mno_enterprise/jpi/v1/organizations/show.json.jbuilder +15 -0
  117. data/app/views/mno_enterprise/jpi/v1/organizations/show_reduced.json.jbuilder +3 -0
  118. data/app/views/mno_enterprise/jpi/v1/shopping_cart/organizations.json.jbuilder +5 -0
  119. data/app/views/mno_enterprise/jpi/v1/shopping_cart/show.json.jbuilder +59 -0
  120. data/app/views/mno_enterprise/jpi/v1/shopping_cart/show_item.json.jbuilder +34 -0
  121. data/app/views/mno_enterprise/jpi/v1/teams/_team.json.jbuilder +20 -0
  122. data/app/views/mno_enterprise/jpi/v1/teams/index.json.jbuilder +1 -0
  123. data/app/views/mno_enterprise/jpi/v1/teams/show.json.jbuilder +3 -0
  124. data/app/views/mno_enterprise/pages/app_access_unauthorized.html.haml +19 -0
  125. data/app/views/mno_enterprise/pages/app_logout.html.haml +18 -0
  126. data/app/views/mno_enterprise/pages/billing_details_required.html.haml +19 -0
  127. data/app/views/mno_enterprise/pages/loading.html.erb +69 -0
  128. data/app/views/mno_enterprise/provision/_provision_apps.html.haml +42 -0
  129. data/app/views/mno_enterprise/provision/_select_organization.html.haml +17 -0
  130. data/app/views/mno_enterprise/provision/new.html.haml +4 -0
  131. data/app/views/mno_enterprise/webhook/o_auth/authorize.html.haml +26 -0
  132. data/app/views/mno_enterprise/webhook/o_auth/providers/myob.html.haml +29 -0
  133. data/app/views/mno_enterprise/webhook/o_auth/providers/xero.html.haml +34 -0
  134. data/config/initializers/devise.rb +273 -0
  135. data/config/initializers/devise_extension.rb +9 -0
  136. data/config/initializers/devise_log.rb +12 -0
  137. data/config/initializers/health_check.rb +35 -0
  138. data/config/initializers/main_app_version.rb +6 -0
  139. data/config/routes.rb +152 -0
  140. data/lib/mno-enterprise-api.rb +1 -0
  141. data/lib/mno_enterprise/api.rb +14 -0
  142. data/lib/mno_enterprise/api/engine.rb +9 -0
  143. data/lib/mno_enterprise/concerns/controllers/deletion_requests_controller.rb +108 -0
  144. data/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb +34 -0
  145. data/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb +58 -0
  146. data/lib/mno_enterprise/concerns/controllers/jpi/v1/deletion_requests_controller.rb +69 -0
  147. data/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb +76 -0
  148. data/lib/mno_enterprise/concerns/controllers/jpi/v1/organizations_controller.rb +180 -0
  149. data/lib/mno_enterprise/concerns/controllers/org_invites_controller.rb +44 -0
  150. data/lib/mno_enterprise/concerns/controllers/pages_controller.rb +78 -0
  151. data/lib/mno_enterprise/concerns/controllers/provision_controller.rb +71 -0
  152. data/lib/mno_enterprise/concerns/controllers/webhook/o_auth_controller.rb +107 -0
  153. data/lib/mno_enterprise/concerns/mailers/system_notification_mailer.rb +158 -0
  154. data/lib/mno_enterprise/event_logger.rb +32 -0
  155. data/spec/controllers/mno_enterprise/auth/confirmation_controller_spec.rb +68 -0
  156. data/spec/controllers/mno_enterprise/deletion_requests_controller_spec.rb +141 -0
  157. data/spec/controllers/mno_enterprise/impersonate_controller_spec.rb +48 -0
  158. data/spec/controllers/mno_enterprise/jpi/v1/admin/audit_events_controller_spec.rb +51 -0
  159. data/spec/controllers/mno_enterprise/jpi/v1/admin/cloud_apps_controller_spec.rb +92 -0
  160. data/spec/controllers/mno_enterprise/jpi/v1/admin/invoices_controller_spec.rb +159 -0
  161. data/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb +116 -0
  162. data/spec/controllers/mno_enterprise/jpi/v1/admin/tenant_invoices_controller_spec.rb +92 -0
  163. data/spec/controllers/mno_enterprise/jpi/v1/admin/users_controller_spec.rb +136 -0
  164. data/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb +76 -0
  165. data/spec/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller_spec.rb +94 -0
  166. data/spec/controllers/mno_enterprise/jpi/v1/current_users_controller_spec.rb +128 -0
  167. data/spec/controllers/mno_enterprise/jpi/v1/deletion_requests_controller_spec.rb +72 -0
  168. data/spec/controllers/mno_enterprise/jpi/v1/impac/kpis_controller_spec.rb +80 -0
  169. data/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb +115 -0
  170. data/spec/controllers/mno_enterprise/jpi/v1/organizations_controller_spec.rb +516 -0
  171. data/spec/controllers/mno_enterprise/jpi/v1/team_controller_spec.rb +86 -0
  172. data/spec/controllers/mno_enterprise/org_invites_controller_spec.rb +29 -0
  173. data/spec/controllers/mno_enterprise/pages_controller_spec.rb +49 -0
  174. data/spec/controllers/mno_enterprise/provision_controller_spec.rb +94 -0
  175. data/spec/controllers/mno_enterprise/status_controller_spec.rb +34 -0
  176. data/spec/controllers/mno_enterprise/webhook/o_auth_controller_spec.rb +104 -0
  177. data/spec/lib/mno_enterprise/event_logger_spec.rb +28 -0
  178. data/spec/mailer/mno_enterprise/system_notification_mailer_spec.rb +132 -0
  179. data/spec/rails_helper.rb +94 -0
  180. data/spec/requests/devise/authentication_spec.rb +43 -0
  181. data/spec/requests/devise/registration_spec.rb +64 -0
  182. data/spec/routing/devise/confirmation_routing_spec.rb +20 -0
  183. data/spec/routing/devise/passwords_routing_spec.rb +24 -0
  184. data/spec/routing/devise/registrations_routing_spec.rb +16 -0
  185. data/spec/routing/devise/sessions_routing_spec.rb +20 -0
  186. data/spec/routing/mno_enterprise/deletion_requests_controller_routing_spec.rb +20 -0
  187. data/spec/routing/mno_enterprise/impersonate_controller_routing.spec.rb +15 -0
  188. data/spec/routing/mno_enterprise/jpi/v1/admin/audit_events_controller_routing_spec.rb +11 -0
  189. data/spec/routing/mno_enterprise/jpi/v1/admin/cloud_apps_controller_routing_spec.rb +24 -0
  190. data/spec/routing/mno_enterprise/jpi/v1/admin/invoices_controller_routing_spec.rb +37 -0
  191. data/spec/routing/mno_enterprise/jpi/v1/admin/organizations_controller_routing_spec.rb +20 -0
  192. data/spec/routing/mno_enterprise/jpi/v1/admin/tenant_invoices_controller_routing_spec.rb +16 -0
  193. data/spec/routing/mno_enterprise/jpi/v1/admin/users_controller_routing_spec.rb +24 -0
  194. data/spec/routing/mno_enterprise/jpi/v1/app_instances_controller_routing_spec.rb +12 -0
  195. data/spec/routing/mno_enterprise/jpi/v1/app_instances_sync_controller_routing_spec.rb +15 -0
  196. data/spec/routing/mno_enterprise/jpi/v1/current_users_controller_routing_spec.rb +28 -0
  197. data/spec/routing/mno_enterprise/jpi/v1/deletion_requests_controller_routing_spec.rb +24 -0
  198. data/spec/routing/mno_enterprise/jpi/v1/impac/kpis_controller_routing_spec.rb +22 -0
  199. data/spec/routing/mno_enterprise/jpi/v1/marketplace_controller_routing_spec.rb +16 -0
  200. data/spec/routing/mno_enterprise/jpi/v1/organizations_controller_routing_spec.rb +44 -0
  201. data/spec/routing/mno_enterprise/jpi/v1/teams_controller_routing_spec.rb +36 -0
  202. data/spec/routing/mno_enterprise/org_invites_controller_routing_spec.rb +12 -0
  203. data/spec/routing/mno_enterprise/pages_controller_routing_spec.rb +29 -0
  204. data/spec/routing/mno_enterprise/provision_controller_routing_spec.rb +15 -0
  205. data/spec/routing/mno_enterprise/status_controller_routing_spec.rb +19 -0
  206. data/spec/routing/mno_enterprise/webhook/o_auth_controller_routing_spec.rb +27 -0
  207. data/spec/spec_helper.rb +88 -0
  208. metadata +402 -0
@@ -0,0 +1,71 @@
1
+ module MnoEnterprise::Concerns::Controllers::ProvisionController
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
+ before_filter :authenticate_user_or_signup!
11
+
12
+ protected
13
+ # The path used after purchased apps have been provisionned
14
+ def after_provision_path
15
+ # MySpace only defined in frontend
16
+ # This should be overriden by the main app when not loading frontend
17
+ if mno_enterprise.respond_to?(:myspace_path)
18
+ mno_enterprise.myspace_path(anchor: '/')
19
+ else
20
+ main_app.root_path
21
+ end
22
+ end
23
+
24
+ helper_method :after_provision_path # To use in the provision view
25
+ end
26
+
27
+ #==================================================================
28
+ # Class methods
29
+ #==================================================================
30
+ module ClassMethods
31
+ # def some_class_method
32
+ # 'some text'
33
+ # end
34
+ end
35
+
36
+ #==================================================================
37
+ # Instance methods
38
+ #==================================================================
39
+ # GET /provision/new?apps[]=vtiger&organization_id=1
40
+ # TODO: check organization accessibility via ability
41
+ def new
42
+ @apps = params[:apps]
43
+ @organizations = current_user.organizations.to_a
44
+ @organization = @organizations.find { |o| o.id && o.id.to_s == params[:organization_id].to_s }
45
+
46
+ unless @organization
47
+ @organization = @organizations.one? ? @organizations.first : nil
48
+ end
49
+ authorize! :manage_app_instances, @organization
50
+
51
+ # Redirect to dashboard if no applications
52
+ unless @apps && @apps.any?
53
+ redirect_to after_provision_path
54
+ end
55
+ end
56
+
57
+ # POST /provision
58
+ # TODO: check organization accessibility via ability
59
+ def create
60
+ @organization = current_user.organizations.to_a.find { |o| o.id && o.id.to_s == params[:organization_id].to_s }
61
+ authorize! :manage_app_instances, @organization
62
+
63
+ app_instances = []
64
+ params[:apps].each do |product_name|
65
+ app_instances << @organization.app_instances.create(product: product_name)
66
+ end
67
+
68
+ render json: app_instances.map(&:attributes).to_json, status: :created
69
+ end
70
+
71
+ end
@@ -0,0 +1,107 @@
1
+ module MnoEnterprise::Concerns::Controllers::Webhook::OAuthController
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
+ before_filter :authenticate_user!, only: [:authorize, :disconnect, :sync]
11
+ before_filter :redirect_to_lounge_if_unconfirmed
12
+ before_filter :check_permissions, only: [:authorize, :disconnect, :sync]
13
+
14
+ PROVIDERS_WITH_OPTIONS = ['xero','myob']
15
+
16
+ private
17
+ def app_instance
18
+ @app_instance ||= MnoEnterprise::AppInstance.where(uid: params[:id]).first
19
+ end
20
+
21
+ # Redirect with an error if user is unauthorized
22
+ def check_permissions
23
+ unless can?(:manage_app_instances, app_instance.owner)
24
+ redirect_to mnoe_home_path, alert: "You are not authorized to perform this action"
25
+ return false
26
+ end
27
+ true
28
+ end
29
+
30
+ # Return a hash of extra parameters that were passed along with
31
+ # the request
32
+ def extra_params
33
+ params.reject { |k,v| [:controller,:action,:id, :perform].include?(k.to_sym) }
34
+ end
35
+
36
+ # Current user web token
37
+ def wtk
38
+ MnoEnterprise.jwt(user_id: current_user.uid)
39
+ end
40
+
41
+ # Append params to the fragment part of an existing url String
42
+ # add_param("/#/platform/accounts", 'foo', 'bar')
43
+ # => "/#/platform/accounts?foo=bar"
44
+ # add_param("/#/platform/dashboard/he/43?en=690", 'foo', 'bar')
45
+ # => "/#/platform/dashboard/he/43?en=690&foo=bar"
46
+ def add_param_to_fragment(url, param_name, param_value)
47
+ uri = URI(url)
48
+ fragment = URI(uri.fragment || "")
49
+ params = URI.decode_www_form(fragment.query || "") << [param_name, param_value]
50
+ fragment.query = URI.encode_www_form(params)
51
+ uri.fragment = fragment.to_s
52
+ uri.to_s
53
+ end
54
+
55
+ def error_message(error_key)
56
+ case error_key.to_sym
57
+ when :bad_relinking
58
+ %{A different account "#{app_instance.oauth_company}" was previously linked to this application, please re-link the same account.}
59
+ when :unauthorized
60
+ 'We could not validate your credentials, please try again'
61
+ else
62
+ error_key
63
+ end
64
+ end
65
+ end
66
+
67
+ #==================================================================
68
+ # Instance methods
69
+ #==================================================================
70
+ # GET /mnoe/webhook/oauth/:id/authorize
71
+ def authorize
72
+ if params[:redirect_path].present?
73
+ session[:redirect_path] = params[:redirect_path]
74
+ end
75
+
76
+ # Certain providers require options to be selected
77
+ if !params[:perform] && app_instance.app && PROVIDERS_WITH_OPTIONS.include?(app_instance.app.nid.to_s)
78
+ render "mno_enterprise/webhook/o_auth/providers/#{app_instance.app.nid}"
79
+ return
80
+ end
81
+
82
+ @redirect_to = MnoEnterprise.router.authorize_oauth_url(params[:id], extra_params.merge(wtk: wtk))
83
+ end
84
+
85
+ # GET /mnoe/webhook/oauth/:id/callback
86
+ def callback
87
+ path = session.delete(:redirect_path).presence || mnoe_home_path
88
+
89
+ if error_key = params.fetch(:oauth, {})[:error]
90
+
91
+ path = add_param_to_fragment(path.to_s, 'flash', [{msg: error_message(error_key), type: :error}.to_json])
92
+ end
93
+
94
+ redirect_to path
95
+ end
96
+
97
+ # GET /mnoe/webhook/oauth/:id/disconnect
98
+ def disconnect
99
+ redirect_to MnoEnterprise.router.disconnect_oauth_url(params[:id], extra_params.merge(wtk: wtk))
100
+ end
101
+
102
+ # GET /mnoe/webhook/oauth/:id/sync
103
+ def sync
104
+ redirect_to MnoEnterprise.router.sync_oauth_url(params[:id], extra_params.merge(wtk: wtk))
105
+ end
106
+
107
+ end
@@ -0,0 +1,158 @@
1
+ module MnoEnterprise::Concerns::Mailers::SystemNotificationMailer
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
+ helper :application
11
+ DEFAULT_SENDER = { name: MnoEnterprise.default_sender_name, email: MnoEnterprise.default_sender_email }
12
+ end
13
+
14
+ #==================================================================
15
+ # Instance methods
16
+ #==================================================================
17
+
18
+ # Default email sender
19
+ # Override to allow dynamic sender
20
+ def default_sender
21
+ DEFAULT_SENDER
22
+ end
23
+
24
+ # ==> Devise Email
25
+ # Description:
26
+ # Email asking users to confirm their email
27
+ #
28
+ # Mandrill vars:
29
+ # :first_name
30
+ # :last_name
31
+ # :full_name
32
+ # :confirmation_link
33
+ #
34
+ def confirmation_instructions(record, token, opts={})
35
+ template = record.confirmed? && record.unconfirmed_email? ? 'reconfirmation-instructions' : 'confirmation-instructions'
36
+ MandrillClient.deliver(template,
37
+ default_sender,
38
+ recipient(record),
39
+ user_vars(record).merge(confirmation_link: user_confirmation_url(confirmation_token: token))
40
+ )
41
+ end
42
+
43
+ # ==> Devise Email
44
+ # Description:
45
+ # Email providing instructions + link to reset password
46
+ #
47
+ # Mandrill vars:
48
+ # :first_name
49
+ # :last_name
50
+ # :full_name
51
+ # :reset_password_link
52
+ #
53
+ def reset_password_instructions(record, token, opts={})
54
+ MandrillClient.deliver('reset-password-instructions',
55
+ default_sender,
56
+ recipient(record),
57
+ user_vars(record).merge(reset_password_link: edit_user_password_url(reset_password_token: token))
58
+ )
59
+ end
60
+
61
+ # ==> Devise Email
62
+ # Description:
63
+ # Email providing instructions + link to unlock a user account after too many failed attempts
64
+ #
65
+ # Mandrill vars:
66
+ # :first_name
67
+ # :last_name
68
+ # :full_name
69
+ # :unlock_link
70
+ #
71
+ def unlock_instructions(record, token, opts={})
72
+ MandrillClient.deliver('unlock-instructions',
73
+ default_sender,
74
+ recipient(record),
75
+ user_vars(record).merge(unlock_link: user_unlock_url(unlock_token: token))
76
+ )
77
+ end
78
+
79
+ # Description:
80
+ # Send an email inviting the user to join an existing organization. If the user
81
+ # is already confirmed it is directed to the organization invite page where he
82
+ # can accept or decline the invite
83
+ # If the user is not confirmed yet then it is considered a new user and will be directed
84
+ # to the confirmation page
85
+ #
86
+ # Mandrill vars:
87
+ # :organization
88
+ # :team
89
+ # :ref_first_name
90
+ # :ref_last_name
91
+ # :ref_full_name
92
+ # :ref_email
93
+ # :invitee_first_name
94
+ # :invitee_last_name
95
+ # :invitee_full_name
96
+ # :invitee_email
97
+ # :confirmation_link
98
+ #
99
+ def organization_invite(org_invite)
100
+ new_user = !org_invite.user.confirmed?
101
+ confirmation_link = new_user ? user_confirmation_url(confirmation_token: org_invite.user.confirmation_token) : org_invite_url(org_invite, token: org_invite.token)
102
+ email_template = new_user ? 'organization-invite-new-user' : 'organization-invite-existing-user'
103
+
104
+ MandrillClient.deliver(email_template,
105
+ default_sender,
106
+ recipient(org_invite.user,new_user),
107
+ invite_vars(org_invite,new_user).merge(confirmation_link: confirmation_link)
108
+ )
109
+ end
110
+
111
+ # Description:
112
+ # Email providing instructions + link to initiate the account termination
113
+ # process.
114
+ #
115
+ # Mandrill vars:
116
+ # :first_name
117
+ # :last_name
118
+ # :full_name
119
+ # :terminate_account_link
120
+ def deletion_request_instructions(record, deletion_request)
121
+ MandrillClient.deliver('deletion-request-instructions',
122
+ default_sender,
123
+ recipient(record),
124
+ user_vars(record).merge(terminate_account_link: deletion_request_url(deletion_request))
125
+ )
126
+ end
127
+
128
+ protected
129
+
130
+ def recipient(record, new_user = false)
131
+ hash = { email: record.email }
132
+ hash[:name] = "#{record.name} #{record.surname}".strip unless new_user
133
+ hash
134
+ end
135
+
136
+ def user_vars(record)
137
+ {
138
+ first_name: record.name,
139
+ last_name: record.surname,
140
+ full_name: "#{record.name} #{record.surname}".strip
141
+ }
142
+ end
143
+
144
+ def invite_vars(org_invite, new_user = true)
145
+ {
146
+ organization: org_invite.organization.name,
147
+ team: org_invite.team.present? ? org_invite.team.name : nil,
148
+ ref_first_name: org_invite.referrer.name,
149
+ ref_last_name: org_invite.referrer.surname,
150
+ ref_full_name: "#{org_invite.referrer.name} #{org_invite.referrer.surname}".strip,
151
+ ref_email: org_invite.referrer.email,
152
+ invitee_first_name: new_user ? nil : org_invite.user.name,
153
+ invitee_last_name: new_user ? nil : org_invite.user.surname,
154
+ invitee_full_name: new_user ? nil : "#{org_invite.user.name} #{org_invite.user.surname}".strip,
155
+ invitee_email: org_invite.user.email,
156
+ }
157
+ end
158
+ end
@@ -0,0 +1,32 @@
1
+ require 'httparty'
2
+
3
+ module MnoEnterprise
4
+ class EventLogger
5
+ include HTTParty
6
+ base_uri "#{MnoEnterprise.mno_api_private_host || MnoEnterprise.mno_api_host}/api/mnoe/v1/audit_events"
7
+ read_timeout 0.1
8
+ basic_auth MnoEnterprise.tenant_id, MnoEnterprise.tenant_key
9
+
10
+ def self.info(key, current_user_id, description, metadata, object)
11
+ post('', body: {
12
+ data: {
13
+ key: key,
14
+ user_id: current_user_id,
15
+ description: description,
16
+ metadata: format_metadata(metadata, object),
17
+ subject_type: object.class.name,
18
+ subject_id: object.id
19
+ }})
20
+ rescue Net::ReadTimeout
21
+ # Meant to fail
22
+ end
23
+
24
+ def self.format_metadata(metadata, object)
25
+ if metadata.blank? && object.respond_to?(:to_audit_event)
26
+ object.to_audit_event
27
+ else
28
+ metadata
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,68 @@
1
+ require 'rails_helper'
2
+
3
+ module MnoEnterprise
4
+ describe Auth::ConfirmationsController, type: :controller do
5
+ routes { MnoEnterprise::Engine.routes }
6
+
7
+ before { @request.env['devise.mapping'] = Devise.mappings[:user] }
8
+
9
+ let(:unconfirmed_user) { build(:user, :unconfirmed, organizations: [])}
10
+ let(:confirmed_user) { build(:user, organizations: [])}
11
+
12
+
13
+ describe 'GET #show' do
14
+ subject { get :show, confirmation_token: user.confirmation_token }
15
+
16
+ before do
17
+ allow(MnoEnterprise::User).to receive(:find_for_confirmation) { user }
18
+ allow(user).to receive(:save)
19
+ end
20
+
21
+ context 'unconfirmed user' do
22
+ let(:user) { unconfirmed_user }
23
+
24
+ it 'does not sign in the user' do
25
+ subject
26
+ expect(controller.current_user).to be_nil
27
+ end
28
+
29
+ it 'render the template' do
30
+ expect(subject).to render_template('show')
31
+ end
32
+ end
33
+
34
+ context 'confirmed user' do
35
+ let(:user) { confirmed_user }
36
+
37
+ context 'with a new email' do
38
+ let(:email) { 'unconfirmed@example.com' }
39
+
40
+ before do
41
+ user.unconfirmed_email = email
42
+
43
+ api_stub_for(get: "/users?filter[email]=#{email}&limit=1", response: from_api(nil))
44
+ api_stub_for(get: "/org_invites?filter[user_email]=#{email}", response: from_api(nil))
45
+ end
46
+
47
+ it 'sign in the user' do
48
+ subject
49
+ expect(controller.current_user).to eq(user)
50
+ end
51
+
52
+ it 'redirects to the dashboard' do
53
+ expect(subject).to redirect_to(controller.signed_in_root_path(user))
54
+ end
55
+ end
56
+
57
+ it 'does not sign in the user' do
58
+ subject
59
+ expect(controller.current_user).to be_nil
60
+ end
61
+
62
+ it 'returns an error' do
63
+ expect(subject).to render_template("new")
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,141 @@
1
+ require 'rails_helper'
2
+
3
+ # TODO: DRY Specs with shared examples
4
+ module MnoEnterprise
5
+ describe DeletionRequestsController, type: :controller do
6
+ render_views
7
+ routes { MnoEnterprise::Engine.routes }
8
+
9
+ # Stub controller ability
10
+ let!(:ability) { stub_ability }
11
+ before { allow(ability).to receive(:can?).with(any_args).and_return(true) }
12
+
13
+ # Stub model calls
14
+ let(:deletion_req) { build(:deletion_request) }
15
+ let(:user) { build(:user, deletion_request: deletion_req) }
16
+
17
+ before do
18
+ api_stub_for(get: "/users/#{user.id}", response: from_api(user))
19
+ api_stub_for(get: "/users/#{user.id}/deletion_request", response: from_api(user))
20
+ end
21
+
22
+ describe "GET #show'" do
23
+ before { sign_in user }
24
+ subject { get :show, id: deletion_req.token }
25
+
26
+ # TODO: use behavior
27
+ it_behaves_like "a navigatable protected user action"
28
+ # it_behaves_like "a user protected resource"
29
+
30
+ context 'when no current_request' do
31
+ let(:user) { build(:user, deletion_request: nil) }
32
+
33
+ it 'redirects to the root_path' do
34
+ subject
35
+ expect(response).to redirect_to(main_app.root_path)
36
+ end
37
+ end
38
+
39
+ context 'when not the current request' do
40
+ let(:new_deletion_req) { build(:deletion_request) }
41
+ let(:user) { build(:user, deletion_request: new_deletion_req) }
42
+
43
+ it 'redirects to the root_path' do
44
+ subject
45
+ expect(response).to redirect_to(main_app.root_path)
46
+ end
47
+ end
48
+ end
49
+
50
+ describe "PUT #freeze_account" do
51
+ # before { api_stub_for(get: "/deletion_requests/#{deletion_req.id}", response: from_api(deletion_req)) }
52
+ before { api_stub_for(put: "/deletion_requests/#{deletion_req.id}", response: from_api(deletion_req)) }
53
+
54
+ before { sign_in user }
55
+ subject { put :freeze_account, id: deletion_req.token }
56
+
57
+ # TODO: use behavior
58
+ it_behaves_like "a navigatable protected user action"
59
+
60
+ context 'when the request is pending' do
61
+ it 'freezes the account' do
62
+ expect(controller.current_user).to receive(:deletion_request).and_return(deletion_req)
63
+ expect(deletion_req).to receive(:freeze_account!)
64
+ subject
65
+ end
66
+
67
+ it 'redirects to the deletion request' do
68
+ subject
69
+ expect(response).to redirect_to(deletion_request_url(deletion_req))
70
+ end
71
+ end
72
+
73
+ context 'when the request is not pending' do
74
+ let(:deletion_req) { build(:deletion_request, status: 'account_frozen') }
75
+
76
+ it 'does not freezes the account' do
77
+ expect_any_instance_of(MnoEnterprise::DeletionRequest).not_to receive(:freeze_account!)
78
+ subject
79
+ end
80
+
81
+ it 'redirects to the deletion request' do
82
+ subject
83
+ expect(response).to redirect_to(deletion_request_url(deletion_req))
84
+ end
85
+
86
+ it 'displays an error message' do
87
+ subject
88
+ expect(flash[:alert]).to eq("Invalid action")
89
+ end
90
+ end
91
+
92
+ context 'when no valid request' do
93
+ let(:user) { build(:user, deletion_request: nil) }
94
+ it 'redirects to the root_path' do
95
+ subject
96
+ expect(response).to redirect_to(main_app.root_path)
97
+ end
98
+ end
99
+
100
+ end
101
+
102
+ describe "PUT #checkout" do
103
+ before { api_stub_for(put: "/deletion_requests/#{deletion_req.id}", response: from_api(deletion_req)) }
104
+
105
+ before { sign_in user }
106
+ subject { put :checkout, id: deletion_req.token }
107
+
108
+ # TODO: use behavior
109
+ it_behaves_like "a navigatable protected user action"
110
+
111
+ context 'when the request is not account_frozen' do
112
+ let(:deletion_req) { build(:deletion_request, status: 'pending') }
113
+
114
+ # it 'does not freezes the account' do
115
+ # expect_any_instance_of(MnoEnterprise::DeletionRequest).not_to receive(:freeze_account!)
116
+ # subject
117
+ # end
118
+
119
+ it 'redirects to the deletion request' do
120
+ subject
121
+ expect(response).to redirect_to(deletion_request_url(deletion_req))
122
+ end
123
+
124
+ it 'displays an error message' do
125
+ subject
126
+ expect(flash[:alert]).to eq("Invalid action")
127
+ end
128
+ end
129
+
130
+ context 'when no valid request' do
131
+ let(:user) { build(:user, deletion_request: nil) }
132
+ it 'redirects to the root_path' do
133
+ subject
134
+ expect(response).to redirect_to(main_app.root_path)
135
+ end
136
+ end
137
+ end
138
+
139
+ describe "PUT #terminate"
140
+ end
141
+ end