From 737caa288888cc3a239422f717557d35b5e6c660 Mon Sep 17 00:00:00 2001 From: x4d3 Date: Wed, 1 Nov 2017 17:50:45 +0000 Subject: [PATCH 01/10] [MNOE-688] Generate relation_id getter and setter for has_one relationship - Introduce HasOneExtension, generating getter and setter for has_one relations, making them saved in relationships, and allowing their retrieving from a relations cache - Remove useless timestamp method - Rplace is_integer by is_id that is more semantic - Try to not rely on parent_organization --- .../jpi/v1/base_resource_controller.rb | 85 +++++++++++-------- .../jpi/v1/app_instances_controller.rb | 12 +-- .../jpi/v1/app_instances_controller_spec.rb | 51 +++++------ .../models/mno_enterprise/base_resource.rb | 5 ++ .../models/mno_enterprise/orga_relation.rb | 7 +- core/app/models/mno_enterprise/user.rb | 2 +- .../has_one_extension.rb | 30 +++++++ .../mno_enterprise/concerns/models/ability.rb | 14 +-- .../concerns/models/app_instance.rb | 4 +- .../concerns/models/organization.rb | 5 -- .../factories/app_instances.rb | 1 - 11 files changed, 126 insertions(+), 90 deletions(-) create mode 100644 core/lib/json_api_client_extension/has_one_extension.rb diff --git a/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb index 26a5ef0ea..7a2669798 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb @@ -3,50 +3,61 @@ class Jpi::V1::BaseResourceController < ApplicationController before_filter :check_authorization protected - - def timestamp - @timestamp ||= (params[:timestamp] || 0).to_i + def is_id?(string) + # we consider that it is an id, if it's + string.to_i.to_s == string + end + + def orga_relation + @orga_relation ||= begin + id_or_uid = params[:organization_id] + organization_field = is_id?(id_or_uid) ? 'id' : 'uid' + MnoEnterprise::OrgaRelation.where('user.id' => current_user.id, "organization.#{organization_field}" => id_or_uid).first end - - def is_integer?(string) - string.to_i.to_s == string + end + + def parent_organization_id + id_or_uid = params[:organization_id] + if is_id?(id_or_uid) + id_or_uid + else + parent_organization.id end + end - def parent_organization - @parent_organization ||= begin - id_or_uid = params[:organization_id] - query = is_integer?(id_or_uid) ? id_or_uid : {uid: id_or_uid} - o = MnoEnterprise::Organization.includes(:orga_relations, :users).find(query).first - ## check that user is in the organization - o if o && o.orga_relation(current_user) - end + def parent_organization + @parent_organization ||= begin + id_or_uid = params[:organization_id] + query = is_id?(id_or_uid) ? id_or_uid : { uid: id_or_uid } + MnoEnterprise::Organization.find(query).first end - - # Check current user is logged in - # Check organization is valid if specified - def check_authorization - unless current_user - render nothing: true, status: :unauthorized - return false - end - if params[:organization_id] && !parent_organization - render nothing: true, status: :forbidden - return false - end - true + end + + # Check current user is logged in + # Check organization is valid if specified + def check_authorization + unless current_user + render nothing: true, status: :unauthorized + return false end - - def render_not_found(resource, id = params[:id]) - render json: { errors: {message: "#{resource.titleize} not found (id=#{id})", code: 404, params: params} }, status: :not_found + if params[:organization_id] && !orga_relation + render nothing: true, status: :forbidden + return false end + true + end - def render_bad_request(attempted_action, issue) - issue = issue.full_messages if issue.respond_to?(:full_messages) - render json: { errors: {message: "Error while trying to #{attempted_action}: #{issue}", code: 400, params: params} }, status: :bad_request - end + def render_not_found(resource, id = params[:id]) + render json: { errors: { message: "#{resource.titleize} not found (id=#{id})", code: 404, params: params } }, status: :not_found + end - def render_forbidden_request(attempted_action) - render json: { errors: {message: "Error while trying to #{attempted_action}: you do not have permission", code: 403} }, status: :forbidden - end + def render_bad_request(attempted_action, issue) + issue = issue.full_messages if issue.respond_to?(:full_messages) + render json: { errors: { message: "Error while trying to #{attempted_action}: #{issue}", code: 400, params: params } }, status: :bad_request + end + + def render_forbidden_request(attempted_action) + render json: { errors: { message: "Error while trying to #{attempted_action}: you do not have permission", code: 403 } }, status: :forbidden + end end end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/app_instances_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/app_instances_controller.rb index b74982003..93e69cc1d 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/app_instances_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/app_instances_controller.rb @@ -16,25 +16,25 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::AppInstancesController # GET /mnoe/jpi/v1/organization/1/app_instances def index statuses = MnoEnterprise::AppInstance::ACTIVE_STATUSES.join(',') - @app_instances = MnoEnterprise::AppInstance.includes(:app).where(owner_id: parent_organization.id, 'status.in': statuses, 'fulfilled_only': true).to_a.select do |i| + @app_instances = MnoEnterprise::AppInstance.includes(:app).where('owner.id': parent_organization.id, 'status.in': statuses, 'fulfilled_only': true).to_a.select do |i| can?(:access,i) end end # POST /mnoe/jpi/v1/organization/1/app_instances def create - authorize! :manage_app_instances, parent_organization - app_instance = parent_organization.provision_app_instance!(params[:nid]) + authorize! :manage_app_instances, orga_relation + input = { data: { attributes: { app_nid: params[:nid], owner_id: parent_organization_id, owner_type: 'Organization' } } } + app_instance = MnoEnterprise::AppInstance.provision!(input) MnoEnterprise::EventLogger.info('app_add', current_user.id, 'App added', app_instance) head :created end # DELETE /mnoe/jpi/v1/app_instances/1 def destroy - @app_instance = MnoEnterprise::AppInstance.find_one(params[:id]) + @app_instance = MnoEnterprise::AppInstance.find_one(params[:id], :owner) if @app_instance - organization = MnoEnterprise::Organization.find_one(@app_instance.owner_id) - authorize! :manage_app_instances, organization + authorize! :manage_app_instances, current_user.orga_relation(@app_instance.owner) MnoEnterprise::EventLogger.info('app_destroy', current_user.id, 'App destroyed', @app_instance) @app_instance = @app_instance.terminate! end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb index 3eaaee8e6..27cedfb72 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb @@ -14,69 +14,62 @@ module MnoEnterprise # Stub user and user call let(:user) { build(:user) } + let(:organization) { build(:organization) } + let(:orga_relation) { build(:orga_relation) } let!(:current_user_stub) { stub_user(user) } - # Stub organization and association - let!(:organization) { - o = build(:organization, orga_relations: []) - o.orga_relations << build(:orga_relation, user_id: user.id, organization_id: o.id, role: 'Super Admin') - o - } - before { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(orga_relations users)) } + before { stub_api_v2(:get, '/orga_relations', orga_relation, [], { filter: { 'user.id': user.id, 'organization.id': organization.id }, page: { number: 1, size: 1 } }) } describe 'GET #index' do - - let(:app_instance) { build(:app_instance, status: 'running' , under_free_trial: false) } - - before { stub_api_v2(:get, '/app_instances', [app_instance], [:app], {filter: {owner_id: organization.id, 'status.in': MnoEnterprise::AppInstance::ACTIVE_STATUSES.join(','), 'fulfilled_only': true }}) } - + let(:app_instance) { build(:app_instance, status: 'running', under_free_trial: false) } + let!(:stub) { stub_api_v2(:get, '/app_instances', [app_instance], [:app], { filter: { 'owner.id': organization.id, 'status.in': MnoEnterprise::AppInstance::ACTIVE_STATUSES.join(','), fulfilled_only: true } }) } before { sign_in user } subject { get :index, organization_id: organization.id } it_behaves_like 'jpi v1 protected action' describe 'all' do - it { + it do subject - # TODO: Test that the rendered json is the expected one - # expect(assigns(:app_instances)).to eq([app_instance]) - assert_requested(:get, api_v2_url('/app_instances', [:app], {_locale: I18n.locale, filter: {owner_id: organization.id, 'status.in': MnoEnterprise::AppInstance::ACTIVE_STATUSES.join(','), 'fulfilled_only': true }})) - } + expect(subject).to be_successful + expect(stub).to have_been_requested + end end context 'without access to the app_instance' do before { allow(ability).to receive(:can?).with(any_args).and_return(false) } - it { + it do subject expect(assigns(:app_instances)).to be_empty - } + end end end describe 'POST #create' do before { stub_audit_events } let(:app) { build(:app, nid: 'my-app') } - let(:app_instance) { build(:app_instance, app: app, owner: organization, owner_id: organization.id) } + let(:app_instance) { build(:app_instance, app: app, owner: organization) } subject { post :create, organization_id: organization.id, nid: 'my-app' } it_behaves_like 'jpi v1 protected action' + let!(:stub) { stub_api_v2(:post, '/app_instances/provision', app_instance) } before do - stub_api_v2(:post, '/app_instances/provision', app_instance) sign_in user end - it { + it do expect(subject).to be_successful - assert_requested_api_v2(:post, '/app_instances/provision') - } + expect(stub).to have_been_requested + end end describe 'DELETE #destroy' do before { stub_audit_events } - let(:app_instance) { build(:app_instance) } + let(:app_instance) { build(:app_instance, owner: organization) } let(:terminated_app_instance) { build(:app_instance, id: app_instance.id, status: 'terminated') } - before { stub_api_v2(:get, "/app_instances/#{app_instance.id}", app_instance)} - before { stub_api_v2(:delete, "/app_instances/#{app_instance.id}/terminate", terminated_app_instance)} - before { stub_api_v2(:get, "/organizations/#{app_instance.owner_id}")} + before { stub_api_v2(:get, "/app_instances/#{app_instance.id}", app_instance, [:owner]) } + let!(:stub) { stub_api_v2(:delete, "/app_instances/#{app_instance.id}/terminate", terminated_app_instance) } + + before { sign_in user } subject { delete :destroy, id: app_instance.id } @@ -84,7 +77,7 @@ module MnoEnterprise it { subject - assert_requested_api_v2(:delete, "/app_instances/#{app_instance.id}/terminate") + expect(stub).to have_been_requested expect(assigns(:app_instance).status).to eq('terminated') } end diff --git a/core/app/models/mno_enterprise/base_resource.rb b/core/app/models/mno_enterprise/base_resource.rb index 3d07c386f..ecac3da3f 100644 --- a/core/app/models/mno_enterprise/base_resource.rb +++ b/core/app/models/mno_enterprise/base_resource.rb @@ -3,6 +3,7 @@ module MnoEnterprise class BaseResource < ::JsonApiClient::Resource include ActiveModel::Callbacks + include JsonApiClientExtension::HasOneExtension self.site = URI.join(MnoEnterprise.api_host, MnoEnterprise.mno_api_v2_root_path).to_s self.parser = JsonApiClientExtension::CustomParser @@ -75,6 +76,10 @@ def self.process_custom_result(result) end # == Instance Methods ======================================================== + # cache of the loaded relations, used in JsonApiClientExtension::HasOneExtension + def relations + @relations ||= ActiveSupport::HashWithIndifferentAccess.new + end def process_custom_result(result) collect_errors(result.errors) diff --git a/core/app/models/mno_enterprise/orga_relation.rb b/core/app/models/mno_enterprise/orga_relation.rb index 4ee508e1e..de5deefa1 100644 --- a/core/app/models/mno_enterprise/orga_relation.rb +++ b/core/app/models/mno_enterprise/orga_relation.rb @@ -4,8 +4,11 @@ class OrgaRelation < BaseResource property :created_at, type: :time property :updated_at, type: :time # json_api_client map all primary id as string - property :organization_id, type: :string - property :user_id, type: :string + property :role, type: :string + + has_one :organization + has_one :user + end end diff --git a/core/app/models/mno_enterprise/user.rb b/core/app/models/mno_enterprise/user.rb index dba3a9765..a244fbb16 100644 --- a/core/app/models/mno_enterprise/user.rb +++ b/core/app/models/mno_enterprise/user.rb @@ -129,7 +129,7 @@ def role_from_id(organization_id) end def orga_relation_from_id(organization_id) - self.orga_relations.find { |r| r.organization_id == organization_id } + MnoEnterprise::OrgaRelation.where('user.id': id, 'organization.id': organization_id).first end def create_deletion_request! diff --git a/core/lib/json_api_client_extension/has_one_extension.rb b/core/lib/json_api_client_extension/has_one_extension.rb new file mode 100644 index 000000000..491179a5a --- /dev/null +++ b/core/lib/json_api_client_extension/has_one_extension.rb @@ -0,0 +1,30 @@ +module JsonApiClientExtension::HasOneExtension + extend ActiveSupport::Concern + + class_methods do + def has_one(attr_name, options = {}) + class_eval <<-CODE + def #{attr_name}_id=(id) + ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id Use relationships instead") + association = id ? {data: {type: "#{attr_name.to_s.pluralize}", id: id.to_s}} : nil + self.relationships.#{attr_name} = association + end + def #{attr_name}_id + # First we try in the relationship + relationship_definitions = self.relationships.try(:#{attr_name}) + return nil unless relationship_definitions + relationship_definitions.dig(:data, :id) + end + def #{attr_name}=(relation) + self.relationships.#{attr_name} = relation + relations[:#{attr_name}] = relation + end + def #{attr_name} + relations[:#{attr_name}] ||= super + end + + CODE + super + end + end +end diff --git a/core/lib/mno_enterprise/concerns/models/ability.rb b/core/lib/mno_enterprise/concerns/models/ability.rb index efb9d5809..cfdbaa3d0 100644 --- a/core/lib/mno_enterprise/concerns/models/ability.rb +++ b/core/lib/mno_enterprise/concerns/models/ability.rb @@ -43,20 +43,20 @@ def initialize(user) :invite_member, :administrate, :manage_app_instances, - :manage_teams], MnoEnterprise::Organization do |organization| - ['Super Admin','Admin'].include? user.role(organization) + :manage_teams], MnoEnterprise::OrgaRelation do |orga_relation| + ['Super Admin','Admin'].include? orga_relation.role end # To be updated # TODO: replace by organization_id, no need to load a full organization - can :sync_apps, MnoEnterprise::Organization do |organization| - user.role(organization) + can :sync_apps, MnoEnterprise::OrgaRelation |orga_relation| + !!orga_relation end # To be updated # TODO: replace by organization_id, no need to load a full organization - can :check_apps_sync, MnoEnterprise::Organization do |organization| - user.role(organization) + can :check_apps_sync, MnoEnterprise::OrgaRelation do |orga_relation| + !!orga_relation end #=================================================== @@ -151,7 +151,7 @@ def impac_abilities(user) # Abilities for admin user def admin_abilities(user) if user.admin_role.to_s.casecmp('admin').zero? || user.admin_role.to_s.casecmp('staff').zero? - can :manage_app_instances, MnoEnterprise::Organization + can :manage_app_instances, MnoEnterprise::OrgaRelation can :manage_sub_tenant, MnoEnterprise::SubTenant end end diff --git a/core/lib/mno_enterprise/concerns/models/app_instance.rb b/core/lib/mno_enterprise/concerns/models/app_instance.rb index 325f5611c..ca7b466b8 100644 --- a/core/lib/mno_enterprise/concerns/models/app_instance.rb +++ b/core/lib/mno_enterprise/concerns/models/app_instance.rb @@ -11,8 +11,6 @@ module MnoEnterprise::Concerns::Models::AppInstance property :updated_at, type: :time property :app_id, type: :string - property :owner_id, type: :string - # delete /app_instances/:id/terminate custom_endpoint :terminate, on: :member, request_method: :delete custom_endpoint :provision, on: :collection, request_method: :post @@ -22,6 +20,8 @@ module MnoEnterprise::Concerns::Models::AppInstance #============================================================== ACTIVE_STATUSES = [:running, :stopped, :staged, :provisioning, :starting, :stopping, :updating] TERMINATION_STATUSES = [:terminating, :terminated] + + has_one :owner end #================================================================== diff --git a/core/lib/mno_enterprise/concerns/models/organization.rb b/core/lib/mno_enterprise/concerns/models/organization.rb index 5f35d843d..c4fb2f0aa 100644 --- a/core/lib/mno_enterprise/concerns/models/organization.rb +++ b/core/lib/mno_enterprise/concerns/models/organization.rb @@ -94,11 +94,6 @@ def add_user!(user, role = 'Member') MnoEnterprise::OrgaRelation.create!(organization_id: self.id, user_id: user.id, role: role) end - def provision_app_instance!(app_nid) - input = { data: { attributes: { app_nid: app_nid, owner_id: id, owner_type: 'Organization' } } } - MnoEnterprise::AppInstance.provision!(input) - end - def new_credit_card MnoEnterprise::CreditCard.new(owner_id: id, owner_type: 'Organization') end diff --git a/core/lib/mno_enterprise/testing_support/factories/app_instances.rb b/core/lib/mno_enterprise/testing_support/factories/app_instances.rb index 353f6a3fa..4389b2295 100644 --- a/core/lib/mno_enterprise/testing_support/factories/app_instances.rb +++ b/core/lib/mno_enterprise/testing_support/factories/app_instances.rb @@ -25,7 +25,6 @@ per_user_licence 1 app { build(:app, nid: app_nid) } sequence(:owner) { |n| build(:organization, id: n.to_s) } - sequence(:owner_id, &:to_s) end end end From 3810f74cdd00f1f3afb691f0db6f80ac91903acb Mon Sep 17 00:00:00 2001 From: x4d3 Date: Thu, 2 Nov 2017 16:12:34 +0000 Subject: [PATCH 02/10] Improve performance by stopping loading everything in current_user Each controller must be in charge of managing its own payload. --- .../jpi/v1/current_users_controller.rb | 47 +++++++++---------- .../models/mno_enterprise/base_resource.rb | 5 ++ core/app/models/mno_enterprise/user.rb | 8 ++-- .../json_api_client_orm_adapter.rb | 4 +- 4 files changed, 35 insertions(+), 29 deletions(-) diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb index d235a59b6..7b6385f59 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb @@ -1,6 +1,8 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::CurrentUsersController extend ActiveSupport::Concern + INCLUDED_DEPENDENCIES = %i(deletion_requests organizations orga_relations dashboards teams orga_relations.user orga_relations.organization sub_tenant) + #================================================================== # Included methods #================================================================== @@ -17,55 +19,52 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::CurrentUsersController #================================================================== # GET /mnoe/jpi/v1/current_user def show - @user = current_user || MnoEnterprise::User.new(id: nil) + @user = current_user&.load_required(*INCLUDED_DEPENDENCIES) || MnoEnterprise::User.new(id: nil) end # PUT /mnoe/jpi/v1/current_user def update - @user = current_user - @user.attributes = user_params + current_user.attributes = user_params changed_attributes = @user.changed_attributes - @user.save! + current_user.save! + current_user.refresh_user_cache MnoEnterprise::EventLogger.info('user_update', current_user.id, 'User update', @user, changed_attributes) - @user = @user.load_required_dependencies + @user = current_user.load_required(*INCLUDED_DEPENDENCIES) render :show - current_user.refresh_user_cache end # PUT /mnoe/jpi/v1/current_user/register_developer def register_developer - @user = current_user - @user = @user.create_api_credentials! + current_user.create_api_credentials! MnoEnterprise::EventLogger.info('register_developer', current_user.id, 'Developer registration', @user) - @user = @user.load_required_dependencies + @user = current_user.load_required(*INCLUDED_DEPENDENCIES) render :show end # PUT /mnoe/jpi/v1/current_user/update_password def update_password - @user = current_user - @user = @user.update_password!(data: {attributes: password_params}) + current_user.update_password!(data: { attributes: password_params }) MnoEnterprise::EventLogger.info('user_update_password', current_user.id, 'User password change', @user) - @user = @user.load_required_dependencies + @user = current_user.load_required(*INCLUDED_DEPENDENCIES) sign_in @user, bypass: true render :show end private - def user_params - params.require(:user).permit( - :name, :surname, :email, :company, :phone, :website, :phone_country_code, :current_password, :password, :password_confirmation, - settings: [:locale] - ) - end + def user_params + params.require(:user).permit( + :name, :surname, :email, :company, :phone, :website, :phone_country_code, :current_password, :password, :password_confirmation, + settings: [:locale] + ) + end - def password_params - params.require(:user).permit(:current_password, :password, :password_confirmation) - end + def password_params + params.require(:user).permit(:current_password, :password, :password_confirmation) + end - def user_management_enabled? - return head :forbidden unless Settings.dashboard.user_management.enabled - end + def user_management_enabled? + return head :forbidden unless Settings.dashboard.user_management.enabled + end end diff --git a/core/app/models/mno_enterprise/base_resource.rb b/core/app/models/mno_enterprise/base_resource.rb index ecac3da3f..fddb696ef 100644 --- a/core/app/models/mno_enterprise/base_resource.rb +++ b/core/app/models/mno_enterprise/base_resource.rb @@ -81,6 +81,11 @@ def relations @relations ||= ActiveSupport::HashWithIndifferentAccess.new end + # define if the relationship has been loaded (for example by calling include) + def relation_loaded?(relation) + relationships && relationships.has_attribute?(relation) && relationships[relation].key?('data') + end + def process_custom_result(result) collect_errors(result.errors) raise_if_errors diff --git a/core/app/models/mno_enterprise/user.rb b/core/app/models/mno_enterprise/user.rb index a244fbb16..29dc1e782 100644 --- a/core/app/models/mno_enterprise/user.rb +++ b/core/app/models/mno_enterprise/user.rb @@ -7,8 +7,6 @@ class User < BaseResource include ActiveModel::AttributeMethods include ActiveModel::Validations - INCLUDED_DEPENDENCIES = %i(deletion_requests organizations orga_relations dashboards teams sub_tenant) - # ids property :id property :uid, type: :string @@ -129,7 +127,11 @@ def role_from_id(organization_id) end def orga_relation_from_id(organization_id) - MnoEnterprise::OrgaRelation.where('user.id': id, 'organization.id': organization_id).first + if relation_loaded?(:orga_relations) + self.orga_relations.find { |r| r.organization.id == organization_id } + else + MnoEnterprise::OrgaRelation.where('user.id': id, 'organization.id': organization_id).first + end end def create_deletion_request! diff --git a/core/lib/json_api_client_extension/json_api_client_orm_adapter.rb b/core/lib/json_api_client_extension/json_api_client_orm_adapter.rb index 8e08abc5f..3212d558d 100644 --- a/core/lib/json_api_client_extension/json_api_client_orm_adapter.rb +++ b/core/lib/json_api_client_extension/json_api_client_orm_adapter.rb @@ -15,14 +15,14 @@ def column_names # @see OrmAdapter::Base#get! def get!(id) - res = klass.includes(*klass::INCLUDED_DEPENDENCIES).find(wrap_key(id)).first + res = klass.find(wrap_key(id)).first raise JsonApiClient::Errors::ResourceNotFound, "resource not found" unless res res end # @see OrmAdapter::Base#get def get(id) - res = klass.includes(*klass::INCLUDED_DEPENDENCIES).find(wrap_key(id)) + res = klass.find(wrap_key(id)) error = res&.errors&.first if (error && error.code != '404') raise error.detail From d66cf3c8d2e46a01bdca4b75a310ebe4ead4af72 Mon Sep 17 00:00:00 2001 From: x4d3 Date: Fri, 3 Nov 2017 10:29:27 +0000 Subject: [PATCH 03/10] Fix spec --- .../mno_enterprise/impersonate_controller.rb | 2 +- .../jpi/v1/admin/app_answers_controller.rb | 2 +- .../jpi/v1/admin/app_comments_controller.rb | 2 +- .../jpi/v1/admin/app_instances_controller.rb | 2 +- .../impac/dashboard_templates_controller.rb | 50 ++++----- .../jpi/v1/app_instances_sync_controller.rb | 4 +- .../jpi/v1/app_reviews_controller.rb | 2 +- .../jpi/v1/base_resource_controller.rb | 30 ------ .../_template.json.jbuilder | 2 +- .../impac/dashboards/_dashboard.json.jbuilder | 2 +- .../jpi/v1/admin/base_resource_controller.rb | 12 +-- .../jpi/v1/app_instances_controller.rb | 6 +- .../jpi/v1/current_users_controller.rb | 11 +- .../jpi/v1/deletion_requests_controller.rb | 4 +- .../impac/dashboard_templates_controller.rb | 2 +- .../jpi/v1/impac/dashboards_controller.rb | 6 +- .../jpi/v1/impac/widgets_controller.rb | 2 +- .../jpi/v1/marketplace_controller.rb | 15 +-- .../jpi/v1/organizations_controller.rb | 2 +- .../controllers/jpi/v1/products_controller.rb | 4 +- .../jpi/v1/subscription_events_controller.rb | 8 +- .../jpi/v1/subscriptions_controller.rb | 26 ++--- .../controllers/jpi/v1/teams_controller.rb | 44 +++++--- .../concerns/controllers/pages_controller.rb | 2 +- .../controllers/provision_controller.rb | 3 +- .../mailers/system_notification_mailer.rb | 2 +- api/lib/mno_enterprise/csv_importer.rb | 6 +- .../deletion_requests_controller_spec.rb | 23 ++-- .../impersonate_controller_spec.rb | 9 +- .../v1/admin/app_answers_controller_spec.rb | 3 +- .../v1/admin/app_comments_controller_spec.rb | 3 +- .../v1/admin/app_instances_controller_spec.rb | 7 +- .../dashboard_templates_controller_spec.rb | 27 ++--- .../jpi/v1/admin/invites_controller_spec.rb | 14 +-- .../v1/admin/organizations_controller_spec.rb | 7 +- .../jpi/v1/app_answers_controller_spec.rb | 2 +- .../jpi/v1/app_comments_controller_spec.rb | 2 +- .../jpi/v1/app_feedbacks_controller_spec.rb | 2 +- .../jpi/v1/app_instances_controller_spec.rb | 3 +- .../v1/app_instances_sync_controller_spec.rb | 19 ++-- .../jpi/v1/app_questions_controller_spec.rb | 2 +- .../jpi/v1/app_reviews_controller_spec.rb | 2 +- .../jpi/v1/audit_events_controller_spec.rb | 11 +- .../jpi/v1/current_users_controller_spec.rb | 56 +++++++--- .../v1/deletion_requests_controller_spec.rb | 23 ++-- .../dashboard_templates_controller_spec.rb | 11 +- .../v1/impac/dashboards_controller_spec.rb | 9 +- .../jpi/v1/impac/widgets_controller_spec.rb | 21 ++-- .../jpi/v1/marketplace_controller_spec.rb | 8 +- .../jpi/v1/organizations_controller_spec.rb | 100 ++++++++++-------- .../jpi/v1/products_controller_spec.rb | 13 ++- .../v1/subscription_events_controller_spec.rb | 8 +- .../jpi/v1/subscriptions_controller_spec.rb | 9 +- .../jpi/v1/teams_controller_spec.rb | 21 ++-- .../mno_enterprise/pages_controller_spec.rb | 6 +- .../provision_controller_spec.rb | 1 + .../system_notification_mailer_spec.rb | 4 +- .../mno_enterprise/application_controller.rb | 35 ++++++ .../mno_enterprise/impersonate_helper.rb | 2 +- .../models/mno_enterprise/deletion_request.rb | 10 +- .../models/mno_enterprise/orga_relation.rb | 1 - core/app/models/mno_enterprise/user.rb | 14 +-- .../has_one_extension.rb | 9 +- .../mno_enterprise/concerns/models/ability.rb | 38 +++---- .../concerns/models/app_instance.rb | 5 +- .../factories/product_pricing.rb | 2 +- .../mno_enterprise_api_test_helper.rb | 31 ++++-- .../models/mno_enterprise/ability_spec.rb | 13 +-- 68 files changed, 447 insertions(+), 392 deletions(-) diff --git a/api/app/controllers/mno_enterprise/impersonate_controller.rb b/api/app/controllers/mno_enterprise/impersonate_controller.rb index 80c2049ff..10e43604c 100644 --- a/api/app/controllers/mno_enterprise/impersonate_controller.rb +++ b/api/app/controllers/mno_enterprise/impersonate_controller.rb @@ -9,7 +9,7 @@ class ImpersonateController < ApplicationController # GET /impersonate/user/123 def create session[:impersonator_redirect_path] = params[:redirect_path].presence - @user = MnoEnterprise::User.find_one(params[:user_id], :deletion_requests, :organizations, :orga_relations, :dashboards, :teams, :user_access_requests, :sub_tenant) + @user = MnoEnterprise::User.find_one(params[:user_id], :user_access_requests) unless @user.present? return redirect_with_error('User does not exist') end diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller.rb index 14045ed27..7bdd129fa 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller.rb @@ -10,7 +10,7 @@ def create def app_answer_params # for an admin, the organization does not matter - orga_relation = current_user.orga_relations.first + orga_relation = MnoEnterprise::OrgaRelation.where('user.id': current_user.id).first params.require(:app_answer).permit(:description) .merge(reviewer_id: orga_relation.id, reviewer_type: 'OrgaRelation', parent_id: parent.id, reviewable_id: parent.reviewable_id, reviewable_type: 'App') diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller.rb index f3f9d7673..121dc8b28 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller.rb @@ -13,7 +13,7 @@ def create def app_comment_params # for an admin, the organization does not matter - orga_relation = current_user.orga_relations.first + orga_relation = MnoEnterprise::OrgaRelation.where('user.id': current_user.id).first params.require(:app_comment).permit(:description) .merge(reviewer_id: orga_relation.id, reviewer_type: 'OrgaRelation', parent_id: parent.id, reviewable_id: parent.reviewable_id, reviewable_type: 'App') diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller.rb index 4ff61dde0..132ecf8a4 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller.rb @@ -3,7 +3,7 @@ class Jpi::V1::Admin::AppInstancesController < Jpi::V1::Admin::BaseResourceContr # DELETE /mnoe/jpi/v1/app_instances/1 def destroy - app_instance = MnoEnterprise::AppInstance.find_one(params[:id]) + app_instance = MnoEnterprise::AppInstance.find_one(params[:id], :owner) if app_instance MnoEnterprise::EventLogger.info('app_destroy', current_user.id, 'App destroyed', app_instance) diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb index 65576636d..31d600394 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb @@ -1,6 +1,8 @@ module MnoEnterprise class Jpi::V1::Admin::Impac::DashboardTemplatesController < Jpi::V1::Admin::BaseResourceController + before_action :load_organizations, except: [:destroy] + # TODO [APIV2]: [:'widgets.kpis', :'kpis.alerts'] DASHBOARD_DEPENDENCIES = [:widgets, :kpis] @@ -9,6 +11,7 @@ class Jpi::V1::Admin::Impac::DashboardTemplatesController < Jpi::V1::Admin::Base #================================================================== # GET /mnoe/jpi/v1/admin/impac/dashboard_templates def index + dashboard_templates = MnoEnterprise::Dashboard.templates.includes(*DASHBOARD_DEPENDENCIES) if params[:terms] # For search mode @dashboard_templates = [] @@ -19,61 +22,44 @@ def index @dashboard_templates = query.to_a response.headers['X-Total-Count'] = query.meta.record_count end + load_organizations end # GET /mnoe/jpi/v1/admin/impac/dashboard_templates/1 def show - render json: { errors: { message: 'Dashboard template not found' } }, status: :not_found unless dashboard_template.present? + @dashboard_template = MnoEnterprise::Dashboard.find_one!(params[:id], *DASHBOARD_DEPENDENCIES) end # POST /mnoe/jpi/v1/admin/impac/dashboard_templates def create @dashboard_template = MnoEnterprise::Dashboard.new(dashboard_template_params.merge(dashboard_type: 'template')) - - # Abort on failure - unless @dashboard_template.save - return render json: { errors: dashboard_template.errors }, status: :bad_request - end - - MnoEnterprise::EventLogger.info('dashboard_template_create', current_user.id, 'Dashboard Template Creation', dashboard_template) + @dashboard_template.save! + MnoEnterprise::EventLogger.info('dashboard_template_create', current_user.id, 'Dashboard Template Creation', @dashboard_template) + @dashboard_template = @dashboard_template.load_required(*DASHBOARD_DEPENDENCIES) render 'show' end # PATCH/PUT /mnoe/jpi/v1/admin/impac/dashboard_templates/1 def update - return render json: { errors: { message: 'Dashboard template not found' } }, status: :not_found unless dashboard_template - - # Abort on failure - unless dashboard_template.update(dashboard_template_params) - return render json: { errors: dashboard_template.errors }, status: :bad_request - end - - MnoEnterprise::EventLogger.info('dashboard_template_update', current_user.id, 'Dashboard Template Update', dashboard_template) + @dashboard_template = MnoEnterprise::Dashboard.find_one!(params[:id]) + dashboard_template.update!(dashboard_template_params) + @dashboard_template = @dashboard_template.load_required(*DASHBOARD_DEPENDENCIES) + MnoEnterprise::EventLogger.info('dashboard_template_update', current_user.id, 'Dashboard Template Update', @dashboard_template) render 'show' end # DELETE /mnoe/jpi/v1/admin/impac/dashboard_templates/1 def destroy - return render json: { errors: { message: 'Dashboard template not found' } }, status: :not_found unless dashboard_template - - MnoEnterprise::EventLogger.info('dashboard_template_delete', current_user.id, 'Dashboard Template Deletion', dashboard_template) - - # Abort on failure - unless dashboard_template.destroy - return render json: { errors: 'Cannot destroy dashboard template' }, status: :bad_request - end - + @dashboard_template = MnoEnterprise::Dashboard.find_one!(params[:id]) + MnoEnterprise::EventLogger.info('dashboard_template_delete', current_user.id, 'Dashboard Template Deletion', @dashboard_template) + @dashboard_template.destroy! head status: :ok end private - def dashboard_templates - @dashboard_templates ||= MnoEnterprise::Dashboard.templates.includes(*DASHBOARD_DEPENDENCIES) - end - - def dashboard_template - @dashboard_template ||= dashboard_templates.find(params[:id].to_i).first + def load_organizations + @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) end def whitelisted_params @@ -86,7 +72,7 @@ def dashboard_template_params params.require(:dashboard).permit(*whitelisted_params).tap do |whitelisted| whitelisted[:settings] = params[:dashboard][:metadata] || {} end - .except(:metadata) + .except(:metadata) end end end diff --git a/api/app/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller.rb index 61edde5ac..f2dca7897 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller.rb @@ -4,7 +4,7 @@ class Jpi::V1::AppInstancesSyncController < Jpi::V1::BaseResourceController # GET /mnoe/jpi/v1/organization/org-fbba/app_instances_sync def index - authorize! :check_apps_sync, @parent_organization + authorize! :check_apps_sync, orga_relation connectors = parent_organization.app_instances_sync! render json: results(connectors) end @@ -12,7 +12,7 @@ def index # POST /mnoe/jpi/v1/organizations/org-fbba/app_instances_sync def create - authorize! :sync_apps, @parent_organization + authorize! :sync_apps, orga_relation connectors = parent_organization.trigger_app_instances_sync! render json: results(connectors) end diff --git a/api/app/controllers/mno_enterprise/jpi/v1/app_reviews_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/app_reviews_controller.rb index 496d17880..8e63fbfff 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/app_reviews_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/app_reviews_controller.rb @@ -53,7 +53,7 @@ def current_app end def orga_relation - @orga_relation ||= MnoEnterprise::OrgaRelation.where(organization_id: organization_id, user_id: current_user.id).first + @orga_relation ||= MnoEnterprise::OrgaRelation.where('organization.id': organization_id, 'user.id': current_user.id).first end def ensure_app_exists diff --git a/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb index 7a2669798..67d1e78d5 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb @@ -3,36 +3,6 @@ class Jpi::V1::BaseResourceController < ApplicationController before_filter :check_authorization protected - def is_id?(string) - # we consider that it is an id, if it's - string.to_i.to_s == string - end - - def orga_relation - @orga_relation ||= begin - id_or_uid = params[:organization_id] - organization_field = is_id?(id_or_uid) ? 'id' : 'uid' - MnoEnterprise::OrgaRelation.where('user.id' => current_user.id, "organization.#{organization_field}" => id_or_uid).first - end - end - - def parent_organization_id - id_or_uid = params[:organization_id] - if is_id?(id_or_uid) - id_or_uid - else - parent_organization.id - end - end - - def parent_organization - @parent_organization ||= begin - id_or_uid = params[:organization_id] - query = is_id?(id_or_uid) ? id_or_uid : { uid: id_or_uid } - MnoEnterprise::Organization.find(query).first - end - end - # Check current user is logged in # Check organization is valid if specified def check_authorization diff --git a/api/app/views/mno_enterprise/jpi/v1/admin/impac/dashboard_templates/_template.json.jbuilder b/api/app/views/mno_enterprise/jpi/v1/admin/impac/dashboard_templates/_template.json.jbuilder index e35f88993..9b6ee1607 100644 --- a/api/app/views/mno_enterprise/jpi/v1/admin/impac/dashboard_templates/_template.json.jbuilder +++ b/api/app/views/mno_enterprise/jpi/v1/admin/impac/dashboard_templates/_template.json.jbuilder @@ -2,7 +2,7 @@ json.extract! template, :id, :name, :full_name, :currency json.metadata template.settings -json.data_sources template.organizations(current_user.organizations).compact.map do |org| +json.data_sources template.organizations(@organizations).compact.map do |org| json.id org.id json.uid org.uid json.label org.name diff --git a/api/app/views/mno_enterprise/jpi/v1/impac/dashboards/_dashboard.json.jbuilder b/api/app/views/mno_enterprise/jpi/v1/impac/dashboards/_dashboard.json.jbuilder index e18e6cef8..2b36a495b 100644 --- a/api/app/views/mno_enterprise/jpi/v1/impac/dashboards/_dashboard.json.jbuilder +++ b/api/app/views/mno_enterprise/jpi/v1/impac/dashboards/_dashboard.json.jbuilder @@ -2,7 +2,7 @@ json.extract! dashboard, :id, :name, :full_name, :currency json.metadata dashboard.settings -json.data_sources dashboard.organizations(current_user.organizations).compact.map do |org| +json.data_sources dashboard.organizations(@organizations).compact.map do |org| json.id org.id json.uid org.uid json.label org.name diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb index 2a9e2638d..2fa9f32d1 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb @@ -12,11 +12,7 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Admin::BaseResourceControl end protected - - def timestamp - @timestamp ||= (params[:timestamp] || 0).to_i - end - + # Check current user is logged in # Check organization is valid if specified def check_authorization @@ -28,14 +24,14 @@ def check_authorization end def render_not_found(resource = controller_name.singularize, id = params[:id]) - render json: { errors: {message: "#{resource.titleize} not found (id=#{id})", code: 404, params: params} }, status: :not_found + render json: { errors: { message: "#{resource.titleize} not found (id=#{id})", code: 404, params: params } }, status: :not_found end def render_bad_request(attempted_action, issue) - render json: { errors: {message: "Error while trying to #{attempted_action}: #{issue}", code: 400, params: params} }, status: :bad_request + render json: { errors: { message: "Error while trying to #{attempted_action}: #{issue}", code: 400, params: params } }, status: :bad_request end def render_forbidden_request(attempted_action) - render json: { errors: {message: "Error while trying to #{attempted_action}: you do not have permission", code: 403} }, status: :forbidden + render json: { errors: { message: "Error while trying to #{attempted_action}: you do not have permission", code: 403 } }, status: :forbidden end end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/app_instances_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/app_instances_controller.rb index 93e69cc1d..ba3e41723 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/app_instances_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/app_instances_controller.rb @@ -16,7 +16,7 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::AppInstancesController # GET /mnoe/jpi/v1/organization/1/app_instances def index statuses = MnoEnterprise::AppInstance::ACTIVE_STATUSES.join(',') - @app_instances = MnoEnterprise::AppInstance.includes(:app).where('owner.id': parent_organization.id, 'status.in': statuses, 'fulfilled_only': true).to_a.select do |i| + @app_instances = MnoEnterprise::AppInstance.includes(:app).where('owner.id': parent_organization_id, 'status.in': statuses, 'fulfilled_only': true).to_a.select do |i| can?(:access,i) end end @@ -24,8 +24,8 @@ def index # POST /mnoe/jpi/v1/organization/1/app_instances def create authorize! :manage_app_instances, orga_relation - input = { data: { attributes: { app_nid: params[:nid], owner_id: parent_organization_id, owner_type: 'Organization' } } } - app_instance = MnoEnterprise::AppInstance.provision!(input) + app_instance = MnoEnterprise::AppInstance.provision!(params[:nid], parent_organization_id, 'Organization' ) + app_instance = app_instance.load_required(:owner) MnoEnterprise::EventLogger.info('app_add', current_user.id, 'App added', app_instance) head :created end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb index 7b6385f59..8b37a2080 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/current_users_controller.rb @@ -1,7 +1,7 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::CurrentUsersController extend ActiveSupport::Concern - INCLUDED_DEPENDENCIES = %i(deletion_requests organizations orga_relations dashboards teams orga_relations.user orga_relations.organization sub_tenant) + INCLUDED_DEPENDENCIES = %i(organizations orga_relations dashboards teams orga_relations.user orga_relations.organization sub_tenant) #================================================================== # Included methods @@ -25,10 +25,10 @@ def show # PUT /mnoe/jpi/v1/current_user def update current_user.attributes = user_params - changed_attributes = @user.changed_attributes + changed_attributes = current_user.changed_attributes current_user.save! current_user.refresh_user_cache - MnoEnterprise::EventLogger.info('user_update', current_user.id, 'User update', @user, changed_attributes) + MnoEnterprise::EventLogger.info('user_update', current_user.id, 'User update', current_user, changed_attributes) @user = current_user.load_required(*INCLUDED_DEPENDENCIES) render :show end @@ -36,16 +36,15 @@ def update # PUT /mnoe/jpi/v1/current_user/register_developer def register_developer current_user.create_api_credentials! - MnoEnterprise::EventLogger.info('register_developer', current_user.id, 'Developer registration', @user) + MnoEnterprise::EventLogger.info('register_developer', current_user.id, 'Developer registration', current_user) @user = current_user.load_required(*INCLUDED_DEPENDENCIES) render :show - end # PUT /mnoe/jpi/v1/current_user/update_password def update_password current_user.update_password!(data: { attributes: password_params }) - MnoEnterprise::EventLogger.info('user_update_password', current_user.id, 'User password change', @user) + MnoEnterprise::EventLogger.info('user_update_password', current_user.id, 'User password change', current_user) @user = current_user.load_required(*INCLUDED_DEPENDENCIES) sign_in @user, bypass: true render :show diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/deletion_requests_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/deletion_requests_controller.rb index eda25f72c..4c55cc98b 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/deletion_requests_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/deletion_requests_controller.rb @@ -24,7 +24,7 @@ module ClassMethods #================================================================== # POST /deletion_request.json def create - @deletion_request = current_user.create_deletion_request! + @deletion_request = MnoEnterprise::DeletionRequest.create!(deletable: current_user) # TODO: deliver_later => need to use user#id and deletion_request#id MnoEnterprise::SystemNotificationMailer.deletion_request_instructions(current_user, @deletion_request).deliver_now render json: @deletion_request, status: :created @@ -33,7 +33,6 @@ def create # PUT /deletion_request/1/resend.json def resend @deletion_request = current_user.current_deletion_request - # Check that the user has a deletion_request in progress # and that the token provided (params[:id]) matches the # deletion_request token @@ -59,4 +58,5 @@ def destroy head :bad_request end end + end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboard_templates_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboard_templates_controller.rb index 693c9aa56..0e58f3f5e 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboard_templates_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboard_templates_controller.rb @@ -8,7 +8,6 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::DashboardTemplatesC # context where it is included rather than being executed in the module's context included do DASHBOARD_DEPENDENCIES = [:widgets, :'widgets.kpis', :kpis, :'kpis.alerts'] - respond_to :json end @@ -18,5 +17,6 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::DashboardTemplatesC # GET /mnoe/jpi/v1/impac/dashboard_templates def index @templates = MnoEnterprise::Dashboard.published_templates.includes(*DASHBOARD_DEPENDENCIES) + @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) end end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb index 18a5880ac..57ca7e956 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb @@ -18,11 +18,13 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::DashboardsControlle # GET /mnoe/jpi/v1/impac/dashboards def index dashboards + @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) end # GET /mnoe/jpi/v1/impac/dashboards/1 # -> GET /api/mnoe/v1/users/1/dashboards def show + @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) render_not_found('dashboard') unless dashboard(*DASHBOARD_DEPENDENCIES) end @@ -35,6 +37,7 @@ def create @dashboard = MnoEnterprise::Dashboard.create!(dashboard_create_params) MnoEnterprise::EventLogger.info('dashboard_create', current_user.id, 'Dashboard Creation', @dashboard) @dashboard = dashboard.load_required(*DASHBOARD_DEPENDENCIES) + @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) render 'show' end @@ -46,7 +49,7 @@ def update # TODO: enable authorization # authorize! :manage_dashboard, dashboard dashboard.update_attributes!(dashboard_update_params) - + @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) # Reload Dashboard @dashboard = dashboard.load_required(DASHBOARD_DEPENDENCIES) render 'show' @@ -73,6 +76,7 @@ def copy # Owner is the current user by default, can be overriden to something else (eg: current organization) @dashboard = template.copy!(current_user, dashboard_params[:name], dashboard_params[:organization_ids]) @dashboard = @dashboard.load_required(DASHBOARD_DEPENDENCIES) + @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) render 'show' end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/widgets_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/widgets_controller.rb index 1a22f40d2..868759e2d 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/widgets_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/widgets_controller.rb @@ -17,7 +17,7 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::WidgetsController # -> GET /api/mnoe/v1/organizations/:id/widgets def index render_not_found('organization') unless parent_organization - @widgets = MnoEnterprise::Widget.find(organization_id: parent_organization.id) + @widgets = MnoEnterprise::Widget.find(organization_id: parent_organization_id) end # POST /mnoe/jpi/v1/impac/dashboards/:id/widgets diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb index c9d0ae307..c571a82d0 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb @@ -20,7 +20,7 @@ def index expires_in 0, public: true, must_revalidate: true # Memoize parent_organization_id if any - org_id = parent_organization_id + org_id = app_instance_organization_id # Compute cache key timestamp app_last_modified = app_relation(org_id).order(updated_at: :desc).select(:updated_at).first&.updated_at || Time.new(0) @@ -45,7 +45,7 @@ def index # GET /mnoe/jpi/v1/marketplace/1(?organization_id=123) def show - @app = app_relation(parent_organization_id).find_one(params[:id]) + @app = app_relation(app_instance_organization_id).find_one(params[:id]) end #================================================================== @@ -59,13 +59,8 @@ def app_relation(org_id = nil) rel end - # Return the organization_id passed as query parameters if the current_user - # has access to it - def parent_organization_id - return nil unless current_user && params[:organization_id].presence - MnoEnterprise::Organization - .select(:id) - .where('id' => params[:organization_id], 'users.id' => current_user.id) - .first&.id + # Return the organization_id passed as query parameters if the current_user has access to it + def app_instance_organization_id + return params[:organization_id] if current_user && params[:organization_id].presence && orga_relation end end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/organizations_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/organizations_controller.rb index d4ae09cfc..5aea7fd57 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/organizations_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/organizations_controller.rb @@ -18,7 +18,7 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::OrganizationsController #================================================================== # GET /mnoe/jpi/v1/organizations def index - @organizations ||= current_user.organizations + @organizations ||= MnoEnterprise::Organization.where('users.id': current_user.id) end # GET /mnoe/jpi/v1/organizations/1 diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/products_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/products_controller.rb index 183da759e..309da42f7 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/products_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/products_controller.rb @@ -11,8 +11,8 @@ def index query = MnoEnterprise::Product.apply_query_params(params).includes(DEPENDENCIES).where(active: true) # Ensure prices include organization-specific markups/discounts - if params[:organization_id] && parent_organization - query = query.with_params(_metadata: { organization_id: parent_organization.id }) + if params[:organization_id] && orga_relation + query = query.with_params(_metadata: { organization_id: parent_organization_id }) end @products = MnoEnterprise::Product.fetch_all(query) diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscription_events_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscription_events_controller.rb index 0f81787de..75275aa72 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscription_events_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscription_events_controller.rb @@ -8,14 +8,14 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::SubscriptionEventsControll #================================================================== # GET /mnoe/jpi/v1/organizations/1/subscriptions/xyz/subscription_events def index - authorize! :manage_app_instances, parent_organization - @subscription_events = fetch_subscription_events(parent_organization.id, params[:subscription_id]) + authorize! :manage_app_instances, orga_relation + @subscription_events = fetch_subscription_events(parent_organization_id, params[:subscription_id]) end # GET /mnoe/jpi/v1/organizations/1/subscriptions/xyz/subscription_events/id def show - authorize! :manage_app_instances, parent_organization - @subscription_event = fetch_subscription_event(parent_organization.id, params[:subscription_id], params[:id]) + authorize! :manage_app_instances, orga_relation + @subscription_event = fetch_subscription_event(parent_organization_id, params[:subscription_id], params[:id]) end protected diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscriptions_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscriptions_controller.rb index 5d3e28983..ebd9584de 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscriptions_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscriptions_controller.rb @@ -8,22 +8,22 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::SubscriptionsController #================================================================== # GET /mnoe/jpi/v1/organizations/1/subscriptions def index - authorize! :manage_app_instances, parent_organization - @subscriptions = fetch_subscriptions(parent_organization.id) + authorize! :manage_app_instances, orga_relation + @subscriptions = fetch_subscriptions(parent_organization_id) end # GET /mnoe/jpi/v1/organizations/1/subscriptions/id def show - authorize! :manage_app_instances, parent_organization - @subscription = fetch_subscription(parent_organization.id, params[:id]) + authorize! :manage_app_instances, orga_relation + @subscription = fetch_subscription(parent_organization_id, params[:id]) end # POST /mnoe/jpi/v1/organizations/1/subscriptions def create - authorize! :manage_app_instances, parent_organization + authorize! :manage_app_instances, orga_relation subscription = MnoEnterprise::Subscription.new(subscription_update_params) - subscription.relationships.organization = MnoEnterprise::Organization.new(id: parent_organization.id) + subscription.relationships.organization = MnoEnterprise::Organization.new(id: parent_organization_id) subscription.relationships.user = MnoEnterprise::User.new(id: current_user.id) if params[:subscription][:product_pricing_id] subscription.relationships.product_pricing = MnoEnterprise::ProductPricing.new(id: params[:subscription][:product_pricing_id]) @@ -34,15 +34,15 @@ def create subscription.save! MnoEnterprise::EventLogger.info('subscription_add', current_user.id, 'Subscription added', subscription) - @subscription = fetch_subscription(parent_organization.id, subscription.id) + @subscription = fetch_subscription(parent_organization_id, subscription.id) render :show end # PUT /mnoe/jpi/v1/organizations/1/subscriptions/abc def update - authorize! :manage_app_instances, parent_organization + authorize! :manage_app_instances, orga_relation - subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization.id, id: params[:id]).first + subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization_id, id: params[:id]).first return render_not_found('subscription') unless subscription if params[:subscription][:product_pricing_id] subscription.relationships.product_pricing = MnoEnterprise::ProductPricing.new(id: params[:subscription][:product_pricing_id]) @@ -55,20 +55,20 @@ def update subscription.modify!(data: subscription.as_json_api) MnoEnterprise::EventLogger.info('subscription_update', current_user.id, 'Subscription updated', subscription) - @subscription = fetch_subscription(parent_organization.id, subscription.id) + @subscription = fetch_subscription(parent_organization_id, subscription.id) render :show end # POST /mnoe/jpi/v1/organizations/1/subscriptions/abc/cancel def cancel - authorize! :manage_app_instances, parent_organization + authorize! :manage_app_instances, orga_relation - subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization.id, id: params[:id]).first + subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization_id, id: params[:id]).first return render_not_found('subscription') unless subscription subscription.cancel! MnoEnterprise::EventLogger.info('subscription_update', current_user.id, 'Subscription cancelled', subscription) - @subscription = fetch_subscription(parent_organization.id, subscription.id) + @subscription = fetch_subscription(parent_organization_id, subscription.id) render :show end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/teams_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/teams_controller.rb index a7735670c..eade6958a 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/teams_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/teams_controller.rb @@ -15,29 +15,33 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::TeamsController #================================================================== # GET /mnoe/jpi/v1/organizations/:organization_id/teams def index - authorize! :read, parent_organization - @teams = MnoEnterprise::Team.includes(:organization, :app_instances, :users).find(organization_id: parent_organization.id) + authorize! :read, orga_relation + @teams = MnoEnterprise::Team.includes(:organization, :app_instances, :users).where('organization.id': parent_organization_id) + load_parent_organization(parent_organization_id) end # GET /mnoe/jpi/v1/teams/:id def show + authorize! :read, orga_relation @team = MnoEnterprise::Team.find_one(params[:id], :organization, :app_instances, :users) - authorize! :read, @team.organization + authorize! :read, current_user.orga_relation(@team.organization) + load_parent_organization(@team.organization.id) end # POST /mnoe/jpi/v1/organizations/:organization_id/teams def create - authorize! :manage_teams, parent_organization - @team = MnoEnterprise::Team.create(create_params) - MnoEnterprise::EventLogger.info('team_add', current_user.id, 'Team created', @team) if @team + authorize! :manage_teams, orga_relation + @team = MnoEnterprise::Team.create!(create_params) + MnoEnterprise::EventLogger.info('team_add', current_user.id, 'Team created', @team) + load_parent_organization(parent_organization_id) render 'show' end # PUT /mnoe/jpi/v1/teams/:id def update - @team = MnoEnterprise::Team.find_one(params[:id], :organization) - @parent_organization = MnoEnterprise::Organization.find_one(@team.organization.id, :orga_relations) - authorize! :manage_teams, @parent_organization + @team = MnoEnterprise::Team.find_one!(params[:id], :organization) + organization = @team.organization + authorize! :manage_teams, current_user.orga_relation(organization) @team.update_attributes!(update_params) # # Update permissions if params[:team] && params[:team][:app_instances] @@ -45,6 +49,7 @@ def update MnoEnterprise::EventLogger.info('team_apps_update', current_user.id, 'Team apps updated', @team, {apps: list.map{|l| l['name']}}) end + load_parent_organization(organization.id) render 'show' end @@ -60,23 +65,28 @@ def remove_users # DELETE /mnoe/jpi/v1/teams/:id def destroy - @team = MnoEnterprise::Team.find_one(params[:id], :organization) - authorize! :manage_teams, @team.organization - MnoEnterprise::EventLogger.info('team_delete', current_user.id, 'Team deleted', @team) if @team + @team = MnoEnterprise::Team.find_one!(params[:id], :organization) + authorize! :manage_teams, current_user.orga_relation(@team.organization) + MnoEnterprise::EventLogger.info('team_delete', current_user.id, 'Team deleted', @team) @team.destroy! head :no_content end private + def load_parent_organization(id) + @parent_organization = MnoEnterprise::Organization.find_one(id, :orga_relations) + end + # Update the members of a team # Reduce duplication between add and remove def update_members(action) - @team = MnoEnterprise::Team.find_one(params[:id], :organization) - authorize! :manage_teams, @team.organization - + @team = MnoEnterprise::Team.find_one!(params[:id], :organization) + organization = @team.organization + authorize! :manage_teams, current_user.orga_relation(organization) if params[:team] && params[:team][:users] id_list = params[:team][:users].map { |h| h[:id].to_i }.compact + # TODO: use a Custom method to update user_ids user_ids = case action when :add_user @team.user_ids | id_list @@ -88,7 +98,7 @@ def update_members(action) {action: action.to_s, user_ids: user_ids}) end @team = @team.load_required(:organization, :users, :app_instances) - @parent_organization = MnoEnterprise::Organization.find_one(@team.organization.id, :orga_relations) + load_parent_organization(organization.id) render 'show' end @@ -102,7 +112,7 @@ def update_params end def create_params - params.require(:team).permit(:name).merge(organization_id: parent_organization.id) + params.require(:team).permit(:name).merge(organization_id: parent_organization_id) end end diff --git a/api/lib/mno_enterprise/concerns/controllers/pages_controller.rb b/api/lib/mno_enterprise/concerns/controllers/pages_controller.rb index ee7b7985f..6d8ef6596 100644 --- a/api/lib/mno_enterprise/concerns/controllers/pages_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/pages_controller.rb @@ -25,7 +25,7 @@ module MnoEnterprise::Concerns::Controllers::PagesController # TODO: Access + existence checks could be added in the future. This is not # mandatory as Mno Enterprise will do it anyway def launch - app_instance = MnoEnterprise::AppInstance.where(uid: params[:id]).first + app_instance = MnoEnterprise::AppInstance.where(uid: params[:id]).includes(:owner).first MnoEnterprise::EventLogger.info('app_launch', current_user.id, 'App launched', app_instance) redirect_to MnoEnterprise.router.launch_url(params[:id], {wtk: MnoEnterprise.jwt(user_id: current_user.uid)}.reverse_merge(request.query_parameters)) end diff --git a/api/lib/mno_enterprise/concerns/controllers/provision_controller.rb b/api/lib/mno_enterprise/concerns/controllers/provision_controller.rb index c03764226..38a43e6cb 100644 --- a/api/lib/mno_enterprise/concerns/controllers/provision_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/provision_controller.rb @@ -67,7 +67,8 @@ def create app_instances = [] params[:apps].each do |product_name| - app_instance = @organization.provision_app_instance!(product_name) + app_instance = MnoEnterprise::AppInstance.provision!(product_name, parent_organization_id, 'Organization' ) + app_instance = app_instance.load_required(:owner) app_instances << app_instance MnoEnterprise::EventLogger.info('app_add', current_user.id, 'App added', app_instance) end diff --git a/api/lib/mno_enterprise/concerns/mailers/system_notification_mailer.rb b/api/lib/mno_enterprise/concerns/mailers/system_notification_mailer.rb index 120424418..2816466db 100644 --- a/api/lib/mno_enterprise/concerns/mailers/system_notification_mailer.rb +++ b/api/lib/mno_enterprise/concerns/mailers/system_notification_mailer.rb @@ -228,7 +228,7 @@ def access_approved_all(user_id, requester_id, access_duration) def send_invoice(recipient_id, invoice_id) recipient = MnoEnterprise::User.select(:email, :name).find(recipient_id).first - invoice = MnoEnterprise::Invoice.find_one(invoice_id) + invoice = MnoEnterprise::Invoice.find_one(invoice_id, :organization) MnoEnterprise::MailClient.deliver( 'invoice', default_sender, diff --git a/api/lib/mno_enterprise/csv_importer.rb b/api/lib/mno_enterprise/csv_importer.rb index 056c190ef..1a41166cd 100644 --- a/api/lib/mno_enterprise/csv_importer.rb +++ b/api/lib/mno_enterprise/csv_importer.rb @@ -46,7 +46,7 @@ def self.process(file_path) if event_type == :added address = MnoEnterprise::Address.new( - city: row['city'], + city: row['city'], country_code: row['country'], street: [row['address1'], row['address2']].reject(&:blank?).join(' '), state_code: row['state_province'], @@ -72,10 +72,10 @@ def self.process(file_path) user.phone = row['phone'] user.save - orga_relation = MnoEnterprise::OrgaRelation.where(user_id: user.id, organization_id: organization.id).first + orga_relation = MnoEnterprise::OrgaRelation.where('user.id': user.id, 'organization.id': organization.id).first # Add User as Super Admin to Organization if he is not already in it unless orga_relation - MnoEnterprise::OrgaRelation.create(user_id: user.id, organization_id: organization.id, role: 'Super Admin') + MnoEnterprise::OrgaRelation.create(user: user, organization: organization, role: 'Super Admin') end end report diff --git a/api/spec/controllers/mno_enterprise/deletion_requests_controller_spec.rb b/api/spec/controllers/mno_enterprise/deletion_requests_controller_spec.rb index 70440d745..cdd1b1992 100644 --- a/api/spec/controllers/mno_enterprise/deletion_requests_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/deletion_requests_controller_spec.rb @@ -5,6 +5,15 @@ module MnoEnterprise render_views routes { MnoEnterprise::Engine.routes } + # Time needs to be frozen for DeletionRequest + before do + Timecop.freeze(Time.local(1985, 9, 17)) + end + + after do + Timecop.return + end + def main_app Rails.application.class.routes.url_helpers end @@ -15,9 +24,9 @@ def main_app # Stub model calls let(:deletion_req) { build(:deletion_request) } - let(:user) { build(:user, deletion_requests: [deletion_req]) } + let(:user) { build(:user) } let!(:current_user_stub) { stub_user(user) } - + let!(:stub) { stub_deletion_requests(user, [deletion_req]) } describe 'GET #show' do before { sign_in user } @@ -27,8 +36,7 @@ def main_app it_behaves_like 'a navigatable protected user action' context 'when no current_request' do - let(:user) { build(:user, deletion_request: nil) } - + let!(:stub) { stub_deletion_requests(user, []) } it 'redirects to the root_path' do subject expect(response).to redirect_to(main_app.root_path) @@ -37,7 +45,7 @@ def main_app context 'when not the current request' do let(:new_deletion_req) { build(:deletion_request) } - let(:user) { build(:user, deletion_request: new_deletion_req) } + let!(:stub) { stub_deletion_requests(user, [new_deletion_req]) } it 'redirects to the root_path' do subject @@ -47,6 +55,7 @@ def main_app end describe 'PUT #freeze_account' do + before { stub_api_v2(:patch, "/deletion_requests/#{deletion_req.id}/freeze", deletion_req) } before { stub_api_v2(:put, "/deletion_requests/#{deletion_req.id}", deletion_req) } @@ -88,7 +97,7 @@ def main_app end context 'when no valid request' do - let(:user) { build(:user, deletion_request: nil) } + let!(:stub) { stub_deletion_requests(user, []) } it 'redirects to the root_path' do subject expect(response).to redirect_to(main_app.root_path) @@ -121,7 +130,7 @@ def main_app end context 'when no valid request' do - let(:user) { build(:user, deletion_request: nil) } + let!(:stub) { stub_deletion_requests(user, []) } it 'redirects to the root_path' do subject expect(response).to redirect_to(main_app.root_path) diff --git a/api/spec/controllers/mno_enterprise/impersonate_controller_spec.rb b/api/spec/controllers/mno_enterprise/impersonate_controller_spec.rb index c430eb993..be2ea4182 100644 --- a/api/spec/controllers/mno_enterprise/impersonate_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/impersonate_controller_spec.rb @@ -8,12 +8,11 @@ module MnoEnterprise let(:user) { build(:user, :admin) } let(:user2) { build(:user) } before do - stub_user(user) - stub_api_v2(:get, "/users/#{user2.id}", user2, %i(deletion_requests organizations orga_relations dashboards teams user_access_requests sub_tenant)) - + stub_api_v2(:get, "/users/#{user.id}", user) + stub_api_v2(:get, "/users/#{user.id}", user, %i(user_access_requests)) + stub_api_v2(:get, "/users/#{user2.id}", user2, %i(user_access_requests)) stub_api_v2(:patch, "/users/#{user.id}") stub_api_v2(:patch, "/users/#{user2.id}") - end before { stub_audit_events } @@ -37,7 +36,7 @@ module MnoEnterprise end context 'when the user does not exist' do - before { stub_api_v2(:get, '/users/crappyId', [], %i(deletion_requests organizations orga_relations dashboards teams user_access_requests sub_tenant)) } + before { stub_api_v2(:get, '/users/crappyId', [], %i(user_access_requests)) } subject { get :create, user_id: 'crappyId', dhbRefId: 10 } it do is_expected.to redirect_to('/admin/#!?flash=%7B%22msg%22%3A%22User+does+not+exist%22%2C%22type%22%3A%22error%22%7D') diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller_spec.rb index b934b778f..502159999 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_answers_controller_spec.rb @@ -11,7 +11,7 @@ module MnoEnterprise #=============================================== # Assignments #=============================================== - let(:user) { build(:user, :admin, orga_relations: [orga_relation]) } + let(:user) { build(:user, :admin) } let!(:orga_relation) { build(:orga_relation) } let!(:current_user_stub) { stub_user(user) } let(:question) { build(:question) } @@ -31,6 +31,7 @@ module MnoEnterprise before do stub_api_v2(:get, "/questions/#{question.id}", question) stub_api_v2(:post, '/answers', answer) + stub_api_v2(:get, '/orga_relations', [orga_relation], [], {filter: {'user.id': user.id}, page: one_page}) end subject { post :create, app_answer: params, question_id: question.id } diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller_spec.rb index f14ebef88..365a3fe57 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_comments_controller_spec.rb @@ -11,7 +11,7 @@ module MnoEnterprise #=============================================== # Assignments #=============================================== - let(:user) { build(:user, :admin, orga_relations: [orga_relation]) } + let(:user) { build(:user, :admin) } let!(:orga_relation) { build(:orga_relation) } let!(:current_user_stub) { stub_user(user) } let(:feedback) { build(:feedback) } @@ -31,6 +31,7 @@ module MnoEnterprise before do stub_api_v2(:get, "/feedbacks/#{feedback.id}", feedback) stub_api_v2(:post, '/comments', comment) + stub_api_v2(:get, '/orga_relations', [orga_relation], [], {filter: {'user.id': user.id}, page: one_page}) end subject { post :create, app_comment: params, feedback_id: feedback.id } diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller_spec.rb index 1173769d7..512af63f1 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/app_instances_controller_spec.rb @@ -10,7 +10,8 @@ module MnoEnterprise before { request.env['HTTP_ACCEPT'] = 'application/json' } before { stub_audit_events } - let(:user) { build(:user, :admin, :with_organizations) } + let(:user) { build(:user, :admin) } + let(:organization) { build(:organization) } let!(:current_user_stub) { stub_user(user) } before do @@ -19,9 +20,9 @@ module MnoEnterprise describe 'DELETE #destroy' do # Stub AppInstance - let(:app_instance) { build(:app_instance) } + let(:app_instance) { build(:app_instance, owner: organization) } - before { stub_api_v2(:get, "/app_instances/#{app_instance.id}", app_instance) } + before { stub_api_v2(:get, "/app_instances/#{app_instance.id}", app_instance, [:owner]) } let!(:stub) { stub_api_v2(:delete, "/app_instances/#{app_instance.id}/terminate") } subject { delete :destroy, id: app_instance.id } diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller_spec.rb index 7e4df8b47..c2a1552e0 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller_spec.rb @@ -10,16 +10,15 @@ module MnoEnterprise let(:dashboard_dependencies) { [:widgets, :kpis] } - let(:user) { build(:user, :admin, :with_organizations) } - let(:org) { user.organizations.first || build(:organization, users: [user]) } + let(:user) { build(:user, :admin) } + let(:organization) { build(:organization) } let(:metadata) { { hist_parameters: { from: '2015-01-01', to: '2015-03-31', period: 'MONTHLY' } } } let(:widget) { build(:impac_widget) } let(:d_kpi) { build(:impac_kpi) } - # let(:w_kpi) { build(:impac_kpi, widget: widget) } let(:template) do build(:impac_dashboard, dashboard_type: 'template', - organization_ids: [org.uid], + organization_ids: [organization.uid], currency: 'EUR', settings: metadata, owner_type: nil, @@ -43,6 +42,7 @@ def hash_for_kpi(kpi) "targets" => kpi.targets } end + let(:hash_for_widget) do { "id" => widget.id, @@ -61,7 +61,7 @@ def hash_for_kpi(kpi) "full_name" => template.full_name, "currency" => 'EUR', "metadata" => metadata.deep_stringify_keys, - "data_sources" => [{ "id" => org.id, "uid" => org.uid, "label" => org.name}], + "data_sources" => [{ "id" => organization.id, "uid" => organization.uid, "label" => organization.name }], "kpis" => [hash_for_kpi(d_kpi)], "widgets" => [hash_for_widget], "published" => true @@ -71,7 +71,7 @@ def hash_for_kpi(kpi) before do stub_user(user) sign_in user - + stub_api_v2(:get, '/organizations', [organization], [], filter: { 'user.ids': user.id }) stub_audit_events end @@ -94,7 +94,7 @@ def hash_for_kpi(kpi) subject { get :show, id: template.id } before do - stub_api_v2(:get, "/dashboards/#{template.id}", [template], dashboard_dependencies, filter: { 'dashboard_type' => 'template' }) + stub_api_v2(:get, "/dashboards/#{template.id}", template, dashboard_dependencies) end it_behaves_like "a jpi v1 admin action" @@ -125,7 +125,8 @@ def hash_for_kpi(kpi) subject { post :create, dashboard: template_params } before do - stub_api_v2(:post, "/dashboards", [template]) + stub_api_v2(:get, "/dashboards/#{template.id}", template, dashboard_dependencies) + stub_api_v2(:post, '/dashboards', [template]) end # TODO: APIv2 @@ -163,7 +164,8 @@ def hash_for_kpi(kpi) subject { put :update, id: template.id, dashboard: template_params } before do - stub_api_v2(:get, "/dashboards/#{template.id}", [template], dashboard_dependencies, filter: { 'dashboard_type' => 'template' }) + stub_api_v2(:get, "/dashboards/#{template.id}", template) + stub_api_v2(:get, "/dashboards/#{template.id}", template, dashboard_dependencies) stub_api_v2(:patch, "/dashboards/#{template.id}", [template]) end @@ -193,15 +195,14 @@ def hash_for_kpi(kpi) subject { delete :destroy, id: template.id } before do - stub_api_v2(:get, "/dashboards/#{template.id}", [template], dashboard_dependencies, filter: { 'dashboard_type' => 'template' }) - stub_api_v2(:delete, "/dashboards/#{template.id}") + stub_api_v2(:get, "/dashboards/#{template.id}", template) end - + let!(:stub) { stub_api_v2(:delete, "/dashboards/#{template.id}") } it_behaves_like "a jpi v1 admin action" it 'deletes the template' do subject - assert_requested_api_v2(:delete, "/dashboards/#{template.id}") + expect(stub).to have_been_requested end # api_stub should be modified to allow these cases to be stubbed diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/invites_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/invites_controller_spec.rb index 255832446..d2b4f2290 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/invites_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/invites_controller_spec.rb @@ -11,13 +11,13 @@ module MnoEnterprise # Assignments #=============================================== # Stub user and user call - let(:user) { build(:user, admin_role: 'admin') } + let(:user) { build(:user, :admin) } let!(:current_user_stub) { stub_user(user) } before do sign_in user end - let(:organization) { build(:organization, orga_relations: []) } + let(:organization) { build(:organization) } let(:invitee) { build(:user) } let(:invite) { build(:orga_invite, user: invitee, organization: organization, status: 'staged') } @@ -29,15 +29,9 @@ module MnoEnterprise # API stubs before do - allow(MnoEnterprise::User).to receive(:find) do |user_id| - case user_id.to_i - when user.id then user - when invitee.id then invitee - end - end stub_api_v2(:get, "/users/#{invitee.id}", invitee) stub_api_v2(:get, "/organizations/#{organization.id}", organization, [:orga_relations]) - stub_api_v2(:get, '/orga_invites', [invite], [:user, :organization, :team, :referrer], {filter: {organization_id: organization.id, user_id: invitee.id, 'status.in': 'staged,pending'}, page:{number:1, size: 1}}) + stub_api_v2(:get, '/orga_invites', [invite], [:user, :organization, :team, :referrer], { filter: { organization_id: organization.id, user_id: invitee.id, 'status.in': 'staged,pending' }, page: { number: 1, size: 1 } }) #reload stub_api_v2(:get, "/orga_invites/#{invite.id}", invite, [:user]) stub_api_v2(:patch, "/orga_invites/#{invite.id}", invite) @@ -58,7 +52,7 @@ module MnoEnterprise end end - context 'new user' do + context 'new user' do let(:invitee) { build(:user, confirmed_at: nil) } it 'sends the confirmation instructions' do diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb index 6603c7fb8..341aecd58 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb @@ -232,10 +232,9 @@ module MnoEnterprise stub_api_v2(:post, '/users', user2), stub_api_v2(:patch, "/users/#{user1.id}", user1), - stub_api_v2(:get, '/orga_relations', [], [], { filter: { user_id: user1.id, organization_id: organization1.id }, page: { number: 1, size: 1 } }), - stub_api_v2(:get, '/orga_relations', [orga_relation1], [], { filter: { user_id: user2.id, organization_id: organization2.id }, page: { number: 1, size: 1 } }), - - stub_api_v2(:post, '/orga_relations', orga_relation2) + stub_orga_relation(user1, organization1, nil), + stub_orga_relation(user2, organization2, orga_relation2), + stub_api_v2(:post, '/orga_relations', orga_relation1) ] } diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/app_answers_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/app_answers_controller_spec.rb index da0622103..43612852d 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/app_answers_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/app_answers_controller_spec.rb @@ -51,7 +51,7 @@ module MnoEnterprise let(:params) { {organization_id: organization.id, description: 'A Review', foo: 'bar', question_id: 'qid'} } before do - stub_api_v2(:get, '/orga_relations', [orga_relation], [], {filter: {organization_id: organization.id, user_id: user.id}, page: {number: 1, size: 1}}) + stub_orga_relation(user, organization, orga_relation) stub_api_v2(:post, '/answers', answer1) end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/app_comments_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/app_comments_controller_spec.rb index 80774a7dd..de5b77ab5 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/app_comments_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/app_comments_controller_spec.rb @@ -50,7 +50,7 @@ module MnoEnterprise let(:params) { {organization_id: organization.id, description: 'A Review', foo: 'bar', feedback_id: 'fid'} } before do - stub_api_v2(:get, '/orga_relations', [orga_relation], [], {filter: {organization_id: organization.id, user_id: user.id}, page: {number: 1, size: 1}}) + stub_orga_relation(user, organization, orga_relation) stub_api_v2(:post, '/comments', comment1) end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/app_feedbacks_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/app_feedbacks_controller_spec.rb index 36138c700..1d1087861 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/app_feedbacks_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/app_feedbacks_controller_spec.rb @@ -56,7 +56,7 @@ module MnoEnterprise let(:params) { {organization_id: organization.id, description: 'A Review', rating: 5} } let(:feedback) { build(:feedback, id: feedback_id, comments: []) } before do - stub_api_v2(:get, '/orga_relations', [orga_relation], [], {filter: {organization_id: organization.id, user_id: user.id}, page: {number: 1, size: 1}}) + stub_orga_relation(user, organization, orga_relation) stub_api_v2(:post, '/feedbacks', feedback) end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb index 27cedfb72..7e93206fc 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_controller_spec.rb @@ -18,7 +18,7 @@ module MnoEnterprise let(:orga_relation) { build(:orga_relation) } let!(:current_user_stub) { stub_user(user) } - before { stub_api_v2(:get, '/orga_relations', orga_relation, [], { filter: { 'user.id': user.id, 'organization.id': organization.id }, page: { number: 1, size: 1 } }) } + before { stub_orga_relation(user, organization, orga_relation) } describe 'GET #index' do let(:app_instance) { build(:app_instance, status: 'running', under_free_trial: false) } @@ -54,6 +54,7 @@ module MnoEnterprise let!(:stub) { stub_api_v2(:post, '/app_instances/provision', app_instance) } before do sign_in user + stub_api_v2(:get, "/app_instances/#{app_instance.id}", app_instance, [:owner]) end it do diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller_spec.rb index 9fb439fb1..123f2537e 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/app_instances_sync_controller_spec.rb @@ -24,13 +24,12 @@ module MnoEnterprise before { sign_in user } # Stub organization - # Stub organization and association - let!(:organization) { - o = build(:organization, orga_relations: []) - o.orga_relations << build(:orga_relation, user_id: user.id, organization_id: o.id, role: 'Super Admin') - o - } - before { stub_api_v2(:get, '/organizations', [organization], %i(orga_relations users), {filter: {uid: organization.uid}}) } + let(:orga_relation) { build(:orga_relation, role: 'Admin') } + let!(:organization) { build(:organization) } + before do + stub_orga_relation(user, organization, orga_relation, 'uid') + stub_api_v2(:get, '/organizations', [organization], [], { filter: { uid: organization.uid } }) + end # Apps sync let(:connectors) { [ @@ -62,7 +61,7 @@ module MnoEnterprise context 'when no connector is syncing' do let(:connectors) { [ - HashWithIndifferentAccess.new({name: 'a_name', status: 'FAILED', date: nil}) + HashWithIndifferentAccess.new({ name: 'a_name', status: 'FAILED', date: nil }) ] } before { subject } @@ -71,7 +70,7 @@ module MnoEnterprise context 'when connector is pending' do let(:connectors) { [ - HashWithIndifferentAccess.new({name: 'a_name', status: 'PENDING', date: nil}) + HashWithIndifferentAccess.new({ name: 'a_name', status: 'PENDING', date: nil }) ] } before { subject } it { expect(JSON.parse(response.body)['is_syncing']).to be_truthy } @@ -80,7 +79,7 @@ module MnoEnterprise describe 'POST #create' do # Apps sync - let(:sync_results) { {connectors: []} } + let(:sync_results) { { connectors: [] } } before { stub_api_v2(:post, "/organizations/#{organization.id}/trigger_app_instances_sync", [organization_with_connectors]) } diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/app_questions_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/app_questions_controller_spec.rb index 31db2d5ab..7732610d3 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/app_questions_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/app_questions_controller_spec.rb @@ -56,7 +56,7 @@ module MnoEnterprise let(:params) { {organization_id: organization.id, description: 'A Review', foo: 'bar'} } let(:question) { build(:question, id: question_id, answers: []) } before do - stub_api_v2(:get, '/orga_relations', [orga_relation], [], {filter: {organization_id: organization.id, user_id: user.id}, page: {number: 1, size: 1}}) + stub_orga_relation(user, organization, orga_relation) stub_api_v2(:post, '/questions', question) end subject { post :create, id: app.id, app_question: params } diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/app_reviews_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/app_reviews_controller_spec.rb index 829249fb3..35230109c 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/app_reviews_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/app_reviews_controller_spec.rb @@ -52,7 +52,7 @@ module MnoEnterprise describe 'POST #create', focus: true do let(:params) { {organization_id: organization.id, description: 'A Review', rating: 5} } before do - stub_api_v2(:get, '/orga_relations', [orga_relation], [], {filter: {organization_id: organization.id, user_id: user.id}, page: {number: 1, size: 1}}) + stub_orga_relation(user, organization, orga_relation) stub_api_v2(:post, '/reviews', review) end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/audit_events_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/audit_events_controller_spec.rb index 7242b257d..7ceec0ca6 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/audit_events_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/audit_events_controller_spec.rb @@ -17,18 +17,15 @@ module MnoEnterprise # Stub user and mnoe API calls let(:user) { build(:user) } - let!(:organization) { - o = build(:organization, orga_relations: []) - o.orga_relations << build(:orga_relation, user_id: user.id, organization_id: o.id, role: "Super Admin") - o - } + let(:organization) { build(:organization) } + let(:orga_relation) { build(:orga_relation) } let(:audit_event) { build(:audit_event) } let!(:current_user_stub) { stub_user(user) } - before { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(orga_relations users)) } before { stub_api_v2(:get, "/organizations/#{organization.id}", organization) } before do - stub_api_v2(:get, '/audit_events', [audit_event], [], {filter: {organization_id: organization.id}}) + stub_orga_relation(user, organization, orga_relation) + stub_api_v2(:get, '/audit_events', [audit_event], [], { filter: { organization_id: organization.id } }) sign_in user end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/current_users_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/current_users_controller_spec.rb index 39ad42796..ec1fca55b 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/current_users_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/current_users_controller_spec.rb @@ -8,12 +8,21 @@ module MnoEnterprise include MnoEnterprise::ApplicationHelper # For #avatar_url + # Times need to be frozen to deal with deletion requests + before do + Timecop.freeze(Time.local(1985, 9, 17)) + end + + after do + Timecop.return + end + def json_for(res) json_hash_for(res).to_json end def json_hash_for(res) - {'current_user' => hash_for(res)} + { 'current_user' => hash_for(res) } end def hash_for(res) @@ -62,16 +71,14 @@ def hash_for(res) hash['kpi_enabled'] = !!res.kpi_enabled end - hash end - before { stub_audit_events } shared_examples 'a user management action' do context 'when Organization management is disabled' do - before { Settings.merge!(dashboard: {user_management: {enabled: false}}) } + before { Settings.merge!(dashboard: { user_management: { enabled: false } }) } before { sign_in user } after { Settings.reload! } @@ -80,12 +87,25 @@ def hash_for(res) end # Stub user retrieval - let!(:user) { build(:user, :with_deletion_request, :with_organizations, :kpi_enabled) } + let(:organization) { build(:organization) } + let!(:user) { build(:user, :kpi_enabled, organizations: [organization], orga_relations: [orga_relation]) } + + let!(:orga_relation) { build(:orga_relation, organization: organization) } + let!(:current_user_stub) { stub_user(user) } + before do + stub_orga_relation(user, organization, orga_relation) + stub_deletion_requests(user, []) + end + describe 'GET #show' do subject { get :show } + before do + stub_user(user, MnoEnterprise::Concerns::Controllers::Jpi::V1::CurrentUsersController::INCLUDED_DEPENDENCIES) + end + describe 'guest' do it 'is successful' do subject @@ -114,14 +134,14 @@ def hash_for(res) end describe 'PUT #update' do - let(:attrs) { {name: user.name + 'aaa'} } + let(:attrs) { { name: user.name + 'aaa' } } before { updated_user = build(:user, id: user.id) updated_user.attributes = attrs - stub_api_v2(:patch, "/users/#{user.id}", updated_user) + stub_api_v2(:patch, "/users/#{user.id}", updated_user) # user reload - stub_user(updated_user) + stub_user(updated_user, MnoEnterprise::Concerns::Controllers::Jpi::V1::CurrentUsersController::INCLUDED_DEPENDENCIES) } subject { put :update, user: attrs } @@ -141,24 +161,26 @@ def hash_for(res) end describe 'PUT #register_developer' do - before { stub_api_v2(:patch, "/users/#{user.id}/create_api_credentials", user) } - #user reload - before { stub_user(user) } - before { sign_in user } subject { put :register_developer } - + before do + sign_in user + stub_api_v2(:patch, "/users/#{user.id}/create_api_credentials", user) + #user reload + stub_user(user, MnoEnterprise::Concerns::Controllers::Jpi::V1::CurrentUsersController::INCLUDED_DEPENDENCIES) + subject + end describe 'logged in' do - before { subject } it { expect(response).to be_success } end end describe 'PUT #update_password' do - let(:attrs) { {current_password: 'password', password: 'blablabla', password_confirmation: 'blablabla'} } + subject { put :update_password, user: attrs } + + let(:attrs) { { current_password: 'password', password: 'blablabla', password_confirmation: 'blablabla' } } let!(:update_password_stub) { stub_api_v2(:patch, "/users/#{user.id}/update_password", user) } #user reload - before { stub_user(user) } - subject { put :update_password, user: attrs } + before { stub_user(user, MnoEnterprise::Concerns::Controllers::Jpi::V1::CurrentUsersController::INCLUDED_DEPENDENCIES) } it_behaves_like 'a user management action' diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/deletion_requests_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/deletion_requests_controller_spec.rb index f11727070..2a8c82738 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/deletion_requests_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/deletion_requests_controller_spec.rb @@ -7,15 +7,21 @@ module MnoEnterprise routes { MnoEnterprise::Engine.routes } before { request.env['HTTP_ACCEPT'] = 'application/json' } + # Time needs to be frozen for DeletionRequest + before { Timecop.freeze(Time.local(1985, 9, 17)) } + after { Timecop.return } + + # Stub model calls let(:deletion_request) { build(:deletion_request) } - let(:user) { build(:user, deletion_requests: [deletion_request]) } + let(:user) { build(:user) } let!(:current_user_stub) { stub_user(user) } + before { stub_deletion_requests(user, [deletion_request]) } before { sign_in user } describe 'POST #create' do - before {stub_api_v2(:post, '/deletion_requests', deletion_request)} + before { stub_api_v2(:post, '/deletion_requests', deletion_request) } subject { post :create } it_behaves_like 'jpi v1 protected action' @@ -28,10 +34,7 @@ module MnoEnterprise it 'sends the instructions email' do message_delivery = instance_double(ActionMailer::MessageDelivery) expect(message_delivery).to receive(:deliver_now).with(no_args) - - expect(SystemNotificationMailer).to receive(:deletion_request_instructions) - .and_return(message_delivery) - + expect(SystemNotificationMailer).to receive(:deletion_request_instructions).and_return(message_delivery) subject end end @@ -45,17 +48,14 @@ module MnoEnterprise it 'resends the deletion instructions' do message_delivery = instance_double(ActionMailer::MessageDelivery) expect(message_delivery).to receive(:deliver_now).with(no_args) - - expect(SystemNotificationMailer).to receive(:deletion_request_instructions) - .and_return(message_delivery) - + expect(SystemNotificationMailer).to receive(:deletion_request_instructions).and_return(message_delivery) subject end end end describe 'DELETE #destroy' do - before {stub_api_v2(:delete, "/deletion_requests/#{deletion_request.id}")} + before { stub_api_v2(:delete, "/deletion_requests/#{deletion_request.id}") } subject { delete :destroy, id: deletion_request.token } it_behaves_like 'jpi v1 protected action' @@ -66,6 +66,5 @@ module MnoEnterprise end end end - end end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboard_templates_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboard_templates_controller_spec.rb index 49d2f6fb1..b4e78b113 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboard_templates_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboard_templates_controller_spec.rb @@ -10,8 +10,8 @@ module MnoEnterprise let(:dashboard_dependencies) { %w(widgets widgets.kpis kpis kpis.alerts) } - let(:user) { build(:user, :with_organizations) } - let(:org) { user.organizations.first || build(:organization, users: [user]) } + let(:user) { build(:user) } + let(:organization) { build(:organization)} let(:metadata) { { hist_parameters: { from: '2015-01-01', to: '2015-03-31', period: 'MONTHLY' } } } let(:widget) { build(:impac_widget, owner: user) } @@ -20,7 +20,7 @@ module MnoEnterprise let(:template) do build(:impac_dashboard, dashboard_type: 'template', - organization_ids: [org.uid], + organization_ids: [organization.uid], currency: 'EUR', settings: metadata, widgets: [widget], @@ -59,7 +59,7 @@ def hash_for_kpi(kpi) "full_name" => template.full_name, "currency" => 'EUR', "metadata" => metadata.deep_stringify_keys, - "data_sources" => [{ "id" => org.id, "uid" => org.uid, "label" => org.name}], + "data_sources" => [{ "id" => organization.id, "uid" => organization.uid, "label" => organization.name}], "kpis" => [hash_for_kpi(d_kpi)], "widgets" => [hash_for_widget] } @@ -72,7 +72,8 @@ def hash_for_kpi(kpi) subject { get :index } before do - stub_api_v2(:get, "/dashboards", [template], dashboard_dependencies, filter: {dashboard_type: 'template', published: true}) + stub_api_v2(:get, '/organizations', [organization], [], filter: { 'user.ids': user.id}) + stub_api_v2(:get, '/dashboards', [template], dashboard_dependencies, filter: { dashboard_type: 'template', published: true}) end it_behaves_like "jpi v1 protected action" diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboards_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboards_controller_spec.rb index f7b41e054..e55adafc5 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboards_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboards_controller_spec.rb @@ -11,8 +11,8 @@ module MnoEnterprise let(:dashboard_dependencies) { [:widgets, :'widgets.kpis', :kpis, :'kpis.alerts', :'kpis.alerts.recipients'] } # Stub user and user call - let(:org) { build(:organization, users: [], orga_relations: []) } - let!(:user) { build(:user, organizations: [org]) } + let(:organization) { build(:organization) } + let!(:user) { build(:user) } let!(:current_user_stub) { stub_user(user) } let(:metadata) { { hist_parameters: { from: '2015-01-01', to: '2015-03-31', period: 'MONTHLY' } } } @@ -25,7 +25,7 @@ module MnoEnterprise let(:dashboard) do build(:impac_dashboard, dashboard_type: 'dashboard', - organization_ids: [org.uid], + organization_ids: [organization.uid], currency: 'EUR', settings: metadata, widgets: [widget], @@ -76,7 +76,7 @@ def hash_for_kpi(kpi) "full_name" => dashboard.full_name, "currency" => 'EUR', "metadata" => metadata.deep_stringify_keys, - "data_sources" => [{ "id" => org.id, "uid" => org.uid, "label" => org.name }], + "data_sources" => [{ "id" => organization.id, "uid" => organization.uid, "label" => organization.name }], "kpis" => [hash_for_kpi(d_kpi)], "widgets" => [hash_for_widget] } @@ -85,6 +85,7 @@ def hash_for_kpi(kpi) before do sign_in user stub_audit_events + stub_api_v2(:get, '/organizations', [organization], [], filter: { 'user.ids': user.id}) end describe 'GET #index' do diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/impac/widgets_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/impac/widgets_controller_spec.rb index 87f73ab17..8eb5e7fab 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/impac/widgets_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/impac/widgets_controller_spec.rb @@ -13,27 +13,26 @@ module MnoEnterprise # Stub user and user call let!(:user) { build(:user) } + let!(:organization) { build(:organization) } + let!(:orga_relation) { build(:orga_relation) } let!(:current_user_stub) { stub_user(user) } before { sign_in user } + before { stub_orga_relation(user, organization, orga_relation, 'uid') } describe 'GET index' do - let!(:organization) { - o = build(:organization, orga_relations: []) - o.orga_relations << build(:orga_relation, user_id: user.id, organization_id: o.id, role: 'Super Admin') - o - } - let!(:widget) { build(:impac_widget, settings: {organization_ids: [organization.uid]}) } + + let!(:widget) { build(:impac_widget, settings: { organization_ids: [organization.uid] }) } subject { get :index, organization_id: organization.uid } - before { stub_api_v2(:get, '/organizations', [organization], %i(orga_relations users), {filter: {uid: organization.uid}}) } - before { stub_api_v2(:get, '/widgets', [widget], [], {filter: {organization_id: organization.id}}) } + before { stub_api_v2(:get, '/organizations', [organization], [], { filter: { uid: organization.uid } }) } + before { stub_api_v2(:get, '/widgets', [widget], [], { filter: { organization_id: organization.id } }) } it 'returns the widgets' do subject - expect(JSON.parse(response.body)).to eq({'widgets' => [ - {'id' => widget.id, 'endpoint' => widget.endpoint, 'settings' => {'organization_ids' => [organization.uid]}} - ]}) + expect(JSON.parse(response.body)).to eq({ 'widgets' => [ + { 'id' => widget.id, 'endpoint' => widget.endpoint, 'settings' => { 'organization_ids' => [organization.uid] } } + ] }) end end end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb index 13f720430..4e78a5588 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb @@ -127,12 +127,14 @@ def hash_for_apps(apps) subject { get :index, organization_id: organization.id } let!(:organization) { build(:organization) } let!(:user) { build(:user) } + let(:orga_relation) { build(:orga_relation) } let!(:current_user_stub) { stub_user(user) } - before { sign_in user } - before { stub_api_v2(:get, "/organizations", [organization], [], { fields: { organizations: 'id' }, filter: { id: organization.id, 'users.id' => user.id }, page: { number: 1, size: 1 } }) } - before { stub_api_v2(:get, '/apps', [app], DEPENDENCIES, { _metadata: { organization_id: organization.id }, filter: { active: true } }) } before do + sign_in(user) + stub_api_v2(:get, "/organizations", [organization], [], { fields: { organizations: 'id' }, filter: { id: organization.id, 'users.id' => user.id }, page: one_page }) + stub_orga_relation(user, organization, orga_relation) + stub_api_v2(:get, '/apps', [app], DEPENDENCIES, { _metadata: { organization_id: organization.id }, filter: { active: true } }) stub_api_v2(:get, '/apps', [app], [], { _metadata: { organization_id: organization.id }, diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/organizations_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/organizations_controller_spec.rb index 5e45169fd..530ef5b10 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/organizations_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/organizations_controller_spec.rb @@ -21,18 +21,12 @@ module MnoEnterprise # Stub organization + associations let(:metadata) { {} } let!(:organization) { build(:organization, metadata: metadata, orga_invites: [], users: [], orga_relations: [], credit_card: credit_card, invoices: []) } - let(:role) { 'Admin' } - let!(:user) { - u = build(:user, organizations: [organization], orga_relations: [orga_relation], dashboards: []) - orga_relation.user_id = u.id - u - } - let!(:orga_relation) { build(:orga_relation, organization_id: organization.id, role: role) } + let!(:user) { build(:user) } let!(:organization_stub) { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations credit_card invoices)) } # Stub user and user call let!(:current_user_stub) { stub_user(user) } - + let(:role) { 'Admin' } before { sign_in user } # Advanced features - currently disabled @@ -45,7 +39,7 @@ module MnoEnterprise #=============================================== shared_examples 'an organization management action' do context 'when Organization management is disabled' do - before { Settings.merge!(dashboard: {organization_management: {enabled: false}}) } + before { Settings.merge!(dashboard: { organization_management: { enabled: false } }) } after { Settings.reload! } it { is_expected.to have_http_status(:forbidden) } @@ -55,7 +49,10 @@ module MnoEnterprise describe 'GET #index' do subject { get :index } it_behaves_like 'jpi v1 protected action' - + before do + stub_api_v2(:get, '/organizations', [organization], [], { filter: { 'users.id': user.id } }) + stub_orga_relation(user, organization, build(:orga_relation)) + end context 'success' do before { subject } @@ -71,8 +68,10 @@ module MnoEnterprise it_behaves_like 'jpi v1 protected action' + before { stub_orga_relation(user, organization, build(:orga_relation, role: role)) } + context 'success' do - before { subject} + before { subject } it 'returns a complete description of the organization' do expect(response).to be_success @@ -81,20 +80,17 @@ module MnoEnterprise end context 'contains invoices' do + subject { get :show, id: organization.id } - - let(:money) { Money.new(0, 'AUD') } let(:role) { 'Super Admin' } - let(:member_role) { role } - let(:member) { build(:user, id: user.id, email: user.email) } - - before { + let(:money) { Money.new(0, 'AUD') } + before do allow_any_instance_of(MnoEnterprise::Organization).to receive(:current_billing).and_return(money) allow_any_instance_of(MnoEnterprise::Organization).to receive(:current_credit).and_return(money) organization.invoices << invoice - stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations credit_card invoices)) - } - + stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations credit_card invoices)) + end + it 'renders the list of invoices' do subject expect(JSON.parse(response.body)['invoices']).to eq(partial_hash_for_invoices(organization)) @@ -103,12 +99,15 @@ module MnoEnterprise end describe 'POST #create' do - let(:params) { {'name' => organization.name} } + let(:params) { { 'name' => organization.name } } + let(:orga_relation) { build(:orga_relation) } subject { post :create, organization: params } - before { stub_api_v2(:post, '/organizations', organization) } - before { stub_api_v2(:post, '/orga_relations', orga_relation) } - # reloading organization - before { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations)) } + before do + stub_orga_relation(user, organization, orga_relation) + stub_api_v2(:post, '/organizations', organization) + stub_api_v2(:post, '/orga_relations', orga_relation) + stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations)) + end it_behaves_like 'jpi v1 protected action' it_behaves_like 'an organization management action' @@ -128,8 +127,12 @@ module MnoEnterprise describe 'PUT #update' do - let(:params) { {'name' => organization.name + 'a', 'soa_enabled' => !organization.soa_enabled} } - before { stub_api_v2(:patch, "/organizations/#{organization.id}", updated_organization) } + let(:params) { { 'name' => organization.name + 'a', 'soa_enabled' => !organization.soa_enabled } } + before do + stub_api_v2(:patch, "/organizations/#{organization.id}", updated_organization) + stub_orga_relation(user, organization, build(:orga_relation)) + end + let!(:updated_organization) { build(:organization, name: params['name'], id: organization.id, soa_enabled: params['soa_enabled']) } subject { put :update, id: organization.id, organization: params } @@ -196,7 +199,7 @@ module MnoEnterprise end describe 'when payment restrictions are set' do - let(:metadata) { {payment_restriction: [:visa]} } + let(:metadata) { { payment_restriction: [:visa] } } let(:visa) { '4111111111111111' } let(:mastercard) { '5105105105105100' } @@ -227,7 +230,7 @@ module MnoEnterprise it 'returns an error' do subject expect(response).to have_http_status(:bad_request) - expect(JSON.parse(response.body)).to eq({'number' => ['Payment is limited to Visa Card Holders']}) + expect(JSON.parse(response.body)).to eq({ 'number' => ['Payment is limited to Visa Card Holders'] }) end end end @@ -243,7 +246,7 @@ module MnoEnterprise before { stub_api_v2(:patch, "/orga_invites/#{organization.id}", orga_invite) } let(:team) { build(:team, organization: organization) } - let(:params) { [{email: 'newmember@maestrano.com', role: 'Power User', team_id: team.id}] } + let(:params) { [{ email: 'newmember@maestrano.com', role: 'Power User', team_id: team.id }] } subject { put :invite_members, id: organization.id, invites: params } it_behaves_like 'jpi v1 authorizable action' @@ -270,23 +273,26 @@ module MnoEnterprise it 'returns a partial representation of the entity' do subject - expect(JSON.parse(response.body)).to eq({'members' => partial_hash_for_members(organization)}) + expect(JSON.parse(response.body)).to eq({ 'members' => partial_hash_for_members(organization) }) end end end describe 'PUT #update_member' do - + let(:role) { 'Admin' } + let!(:orga_relation) { build(:orga_relation, organization_id: organization.id, role: role) } let(:email) { 'somemember@maestrano.com' } let(:member_role) { 'Member' } let(:member) { build(:user) } let(:email) { member.email } - let(:new_member_role) { 'Power User' } - let(:params) { {email: email, role: new_member_role} } + let(:params) { { email: email, role: new_member_role } } - # reloading organization - before { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations)) } + before do + stub_orga_relation(user, organization, build(:orga_relation)) + # reloading organization + stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations)) + end subject { put :update_member, id: organization.id, member: params } it_behaves_like 'jpi v1 authorizable action' @@ -294,14 +300,16 @@ module MnoEnterprise context 'with user' do let(:member_orga_relation) { build(:orga_relation, user_id: member.id, organization_id: organization.id, role: member_role) } - let(:organization_stub) { + let(:organization_stub) do organization.users << member organization.orga_relations << member_orga_relation stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations credit_card invoices)) - } - before { stub_api_v2(:get, "/orga_relations", [member_orga_relation], [], {filter: {organization_id: organization.id, user_id: member.id}, page:{ number: 1, size: 1}}) } - before { stub_api_v2(:post, "/orga_relations/#{member_orga_relation.id}", orga_relation) } - before { stub_api_v2(:patch, "/orga_relations/#{member_orga_relation.id}") } + end + before do + stub_api_v2(:get, "/orga_relations", [member_orga_relation], [], { filter: { organization_id: organization.id, user_id: member.id }, page: one_page }) + stub_api_v2(:post, "/orga_relations/#{member_orga_relation.id}", orga_relation) + stub_api_v2(:patch, "/orga_relations/#{member_orga_relation.id}") + end # Happy path it 'updates the member role' do @@ -381,7 +389,7 @@ module MnoEnterprise it 'renders a the user list' do subject - expect(JSON.parse(response.body)).to eq({'members' => partial_hash_for_members(organization)}) + expect(JSON.parse(response.body)).to eq({ 'members' => partial_hash_for_members(organization) }) end end @@ -399,7 +407,7 @@ module MnoEnterprise before { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations)) } - let(:params) { {email: 'somemember@maestrano.com'} } + let(:params) { { email: 'somemember@maestrano.com' } } subject { put :remove_member, id: organization.id, member: params } it_behaves_like 'jpi v1 authorizable action' @@ -407,7 +415,7 @@ module MnoEnterprise context 'with user' do before { stub_api_v2(:delete, "/orga_relations/#{member_orga_relation.id}") } - let(:params) { {email: member.email} } + let(:params) { { email: member.email } } it 'removes the member' do subject end @@ -420,7 +428,7 @@ module MnoEnterprise stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(users orga_invites orga_relations credit_card invoices)) } - before { stub_api_v2(:get, "/orga_invites/#{orga_invite.id}/decline")} + before { stub_api_v2(:get, "/orga_invites/#{orga_invite.id}/decline") } it 'removes the member' do subject end @@ -428,7 +436,7 @@ module MnoEnterprise it 'renders a the user list' do subject - expect(JSON.parse(response.body)).to eq({'members' => partial_hash_for_members(organization)}) + expect(JSON.parse(response.body)).to eq({ 'members' => partial_hash_for_members(organization) }) end end end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/products_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/products_controller_spec.rb index 69230c596..e4c2f5201 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/products_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/products_controller_spec.rb @@ -8,24 +8,23 @@ module MnoEnterprise before { request.env['HTTP_ACCEPT'] = 'application/json' } before(:all) do - Settings.merge!(dashboard: {marketplace: {local_products: true}}) + Settings.merge!(dashboard: { marketplace: { local_products: true } }) Rails.application.reload_routes! end # Stub user and user call let!(:user) { build(:user) } + let(:organization) { build(:organization) } let!(:current_user_stub) { stub_user(user) } + before do + stub_orga_relation(user, organization, build(:orga_relation)) + end describe 'GET #index' do subject { get :index, params } let(:params) { {} } let(:product) { build(:product) } - let(:organization) { - o = build(:organization, orga_relations: []) - o.orga_relations << build(:orga_relation, user_id: user.id, organization_id: o.id, role: 'Super Admin') - o - } before { sign_in user } @@ -40,7 +39,7 @@ module MnoEnterprise before { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(orga_relations users)) } before do stub_api_v2(:get, "/products", [product], - [:'values.field', :assets, :categories, :product_pricings, :product_contracts], { filter: { active: true }, _metadata: { organization_id: organization.id } }) + [:'values.field', :assets, :categories, :product_pricings, :product_contracts], { filter: { active: true }, _metadata: { organization_id: organization.id } }) end it_behaves_like 'jpi v1 protected action' diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/subscription_events_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/subscription_events_controller_spec.rb index febcbff57..7c74cf2c0 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/subscription_events_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/subscription_events_controller_spec.rb @@ -21,9 +21,11 @@ module MnoEnterprise let!(:current_user_stub) { stub_user(user) } # Stub organization and association - let!(:organization) { build(:organization, orga_relations: []) } - let!(:orga_relation) { organization.orga_relations << build(:orga_relation, user_id: user.id, organization_id: organization.id, role: 'Super Admin') } - let!(:organization_stub) { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(orga_relations users)) } + let!(:organization) { build(:organization) } + let!(:orga_relation) { build(:orga_relation, role: 'Super Admin') } + before do + stub_orga_relation(user, organization, orga_relation) + end describe 'GET #index' do let(:subscription) { build(:subscription) } diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/subscriptions_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/subscriptions_controller_spec.rb index 33eca247a..801f85aae 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/subscriptions_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/subscriptions_controller_spec.rb @@ -21,10 +21,11 @@ module MnoEnterprise let!(:current_user_stub) { stub_user(user) } # Stub organization and association - let!(:organization) { build(:organization, orga_relations: []) } - let!(:orga_relation) { organization.orga_relations << build(:orga_relation, user_id: user.id, organization_id: organization.id, role: 'Super Admin') } - let!(:organization_stub) { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(orga_relations users)) } - + let!(:organization) { build(:organization) } + let!(:orga_relation) { build(:orga_relation, role: 'Super Admin') } + before do + stub_orga_relation(user, organization, orga_relation) + end # Stub license_assignments association before { allow_any_instance_of(MnoEnterprise::Subscription).to receive(:license_assignments).and_return([]) } diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/teams_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/teams_controller_spec.rb index 079280a0c..0e5af9ed0 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/teams_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/teams_controller_spec.rb @@ -58,18 +58,19 @@ def hash_for_team(team) # Specs #=============================================== describe 'PUT #add_users' do - - let!(:current_user_stub) { stub_user(user) } - - before { stub_api_v2(:get, "/apps", [app]) } - before { stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(orga_relations)) } - before { stub_api_v2(:get, "/teams/#{team.id}", team, %i(organization)) } - before { stub_api_v2(:patch, "/teams/#{team.id}") } - before { stub_audit_events } subject { put :add_users, id: team.id, team: {users: [{id: user.id}]} } + before do + stub_user(user) + stub_orga_relation(user, organization, build(:orga_relation)) + stub_api_v2(:get, "/apps", [app]) + stub_api_v2(:get, "/organizations/#{organization.id}", organization, %i(orga_relations)) + stub_api_v2(:get, "/teams/#{team.id}", team, %i(organization)) + stub_api_v2(:patch, "/teams/#{team.id}") + # team reload + stub_api_v2(:get, "/teams/#{team.id}", team, %i(organization users app_instances)) + stub_audit_events + end - # team reload - before { stub_api_v2(:get, "/teams/#{team.id}", team, %i(organization users app_instances)) } context 'success' do before { subject } diff --git a/api/spec/controllers/mno_enterprise/pages_controller_spec.rb b/api/spec/controllers/mno_enterprise/pages_controller_spec.rb index 705fbcd6c..12ff51fa0 100644 --- a/api/spec/controllers/mno_enterprise/pages_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/pages_controller_spec.rb @@ -16,7 +16,7 @@ module MnoEnterprise before do stub_user(user) - stub_api_v2(:get, '/app_instances', [app_instance], [], {filter:{uid: app_instance.uid}, page:{number: 1, size: 1}}) + stub_api_v2(:get, '/app_instances', [app_instance], [:owner], { filter: { uid: app_instance.uid }, page: one_page }) end describe 'GET #launch' do @@ -28,7 +28,7 @@ module MnoEnterprise it 'redirect to the mno enterprise launch page with a web token' do subject - expect(response).to redirect_to(MnoEnterprise.router.launch_url(app_instance.uid, wtk: MnoEnterprise.jwt({user_id: user.uid}))) + expect(response).to redirect_to(MnoEnterprise.router.launch_url(app_instance.uid, wtk: MnoEnterprise.jwt({ user_id: user.uid }))) end end @@ -41,7 +41,7 @@ module MnoEnterprise it 'redirects to the mno enterprise launch page with a web token and extra params' do subject - expect(response).to redirect_to(MnoEnterprise.router.launch_url(app_instance.uid, wtk: MnoEnterprise.jwt({user_id: user.uid}), specific_parameters: 'specific_parameters_value')) + expect(response).to redirect_to(MnoEnterprise.router.launch_url(app_instance.uid, wtk: MnoEnterprise.jwt({ user_id: user.uid }), specific_parameters: 'specific_parameters_value')) end end diff --git a/api/spec/controllers/mno_enterprise/provision_controller_spec.rb b/api/spec/controllers/mno_enterprise/provision_controller_spec.rb index 0b5dd05ed..cf485542b 100644 --- a/api/spec/controllers/mno_enterprise/provision_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/provision_controller_spec.rb @@ -109,6 +109,7 @@ module MnoEnterprise subject { post :create, params } before do stub_api_v2(:post, "/app_instances/provision", app_instance) + stub_api_v2(:get, "/app_instances/#{app_instance.id}", app_instance, [:owner]) end describe 'guest' do diff --git a/api/spec/mailer/mno_enterprise/system_notification_mailer_spec.rb b/api/spec/mailer/mno_enterprise/system_notification_mailer_spec.rb index dbb0a2310..8eda94c9b 100644 --- a/api/spec/mailer/mno_enterprise/system_notification_mailer_spec.rb +++ b/api/spec/mailer/mno_enterprise/system_notification_mailer_spec.rb @@ -9,7 +9,7 @@ module MnoEnterprise end let(:routes) { MnoEnterprise::Engine.routes.url_helpers } let(:user) { build(:user) } - let(:token) { "1sd5f323S1D5AS" } + let(:token) { '1sd5f323S1D5AS' } let(:deletion_request) { build(:deletion_request) } # Commonly used mandrill variables @@ -183,7 +183,7 @@ def invite_vars(orga_invite) before do Timecop.freeze stub_api_v2(:get, "/users/#{user.id}", user, [], {fields: {users: 'email,name'}}) - stub_api_v2(:get, "/invoices/#{invoice.id}", invoice) + stub_api_v2(:get, "/invoices/#{invoice.id}", invoice, [:organization]) end after { Timecop.return } let(:invoice) { build(:invoice) } diff --git a/core/app/controllers/mno_enterprise/application_controller.rb b/core/app/controllers/mno_enterprise/application_controller.rb index f5d905fb5..86680b12f 100644 --- a/core/app/controllers/mno_enterprise/application_controller.rb +++ b/core/app/controllers/mno_enterprise/application_controller.rb @@ -138,6 +138,41 @@ def after_sign_out_path_for(resource_or_scope) MnoEnterprise.router.after_sign_out_url || super end + #============================================ + # Helper methods + #============================================ + + # test if the provided argument is a id or an uid + # @param [Object] id or uid + def is_id?(string) + string.to_i.to_s == string + end + + def parent_organization_id + id_or_uid = params[:organization_id] + if is_id?(id_or_uid) + id_or_uid + else + parent_organization.id + end + end + + def parent_organization + @parent_organization ||= begin + id_or_uid = params[:organization_id] + query = is_id?(id_or_uid) ? id_or_uid : { uid: id_or_uid } + MnoEnterprise::Organization.find(query).first + end + end + + def orga_relation + @orga_relation ||= begin + id_or_uid = params[:organization_id] + organization_field = is_id?(id_or_uid) ? 'id' : 'uid' + MnoEnterprise::OrgaRelation.where('user.id' => current_user.id, "organization.#{organization_field}" => id_or_uid).first + end + end + private # Append params to the fragment part of an existing url String diff --git a/core/app/helpers/mno_enterprise/impersonate_helper.rb b/core/app/helpers/mno_enterprise/impersonate_helper.rb index 651ec6462..6e4ca5e2b 100644 --- a/core/app/helpers/mno_enterprise/impersonate_helper.rb +++ b/core/app/helpers/mno_enterprise/impersonate_helper.rb @@ -22,7 +22,7 @@ def revert_impersonate def current_impersonator return unless session[:impersonator_user_id] - @admin_user ||= MnoEnterprise::User.find_one(session[:impersonator_user_id], :deletion_requests, :organizations, :orga_relations, :dashboards, :teams, :sub_tenant) + @admin_user ||= MnoEnterprise::User.find_one(session[:impersonator_user_id]) end end diff --git a/core/app/models/mno_enterprise/deletion_request.rb b/core/app/models/mno_enterprise/deletion_request.rb index bc3acbccf..21dda250b 100644 --- a/core/app/models/mno_enterprise/deletion_request.rb +++ b/core/app/models/mno_enterprise/deletion_request.rb @@ -5,11 +5,20 @@ class DeletionRequest < BaseResource custom_endpoint :freeze, on: :member, request_method: :patch + has_one :deletable + #============================================ # CONSTANTS #============================================ EXPIRATION_TIME = 60 #minutes + #============================================ + # Class methods + #============================================ + def self.active(query = where) + query.where('status.ne': 'cancelled', 'created_at.gt': EXPIRATION_TIME.minutes.ago) + end + #============================================ # Instance methods #============================================ @@ -26,7 +35,6 @@ def freeze_account! result = self.freeze process_custom_result(result) end - end end diff --git a/core/app/models/mno_enterprise/orga_relation.rb b/core/app/models/mno_enterprise/orga_relation.rb index de5deefa1..503f71a9e 100644 --- a/core/app/models/mno_enterprise/orga_relation.rb +++ b/core/app/models/mno_enterprise/orga_relation.rb @@ -9,6 +9,5 @@ class OrgaRelation < BaseResource has_one :organization has_one :user - end end diff --git a/core/app/models/mno_enterprise/user.rb b/core/app/models/mno_enterprise/user.rb index 29dc1e782..e9e0dc4ec 100644 --- a/core/app/models/mno_enterprise/user.rb +++ b/core/app/models/mno_enterprise/user.rb @@ -105,8 +105,7 @@ def expire_user_cache def refresh_user_cache self.expire_view_cache - reloaded = self.load_required_dependencies - Rails.cache.write(['user', reloaded.to_key], reloaded) + Rails.cache.write(['user', self.to_key], self) end def load_required_dependencies @@ -139,11 +138,12 @@ def create_deletion_request! end def current_deletion_request - @current_deletion_request ||= if self.account_frozen - self.deletion_requests.sort_by(&:created_at).last - else - self.deletion_requests.select(&:active?).sort_by(&:created_at).first - end + query = if self.account_frozen + MnoEnterprise::DeletionRequest.where + else + MnoEnterprise::DeletionRequest.active + end + query.where('deletable.id': self.id, 'deletable.type': 'users').order(created_at: :desc).first end def update_password!(input) diff --git a/core/lib/json_api_client_extension/has_one_extension.rb b/core/lib/json_api_client_extension/has_one_extension.rb index 491179a5a..e02ad0e72 100644 --- a/core/lib/json_api_client_extension/has_one_extension.rb +++ b/core/lib/json_api_client_extension/has_one_extension.rb @@ -6,14 +6,11 @@ def has_one(attr_name, options = {}) class_eval <<-CODE def #{attr_name}_id=(id) ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id Use relationships instead") - association = id ? {data: {type: "#{attr_name.to_s.pluralize}", id: id.to_s}} : nil - self.relationships.#{attr_name} = association + super end def #{attr_name}_id - # First we try in the relationship - relationship_definitions = self.relationships.try(:#{attr_name}) - return nil unless relationship_definitions - relationship_definitions.dig(:data, :id) + ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id Use relationships instead") + super end def #{attr_name}=(relation) self.relationships.#{attr_name} = relation diff --git a/core/lib/mno_enterprise/concerns/models/ability.rb b/core/lib/mno_enterprise/concerns/models/ability.rb index cfdbaa3d0..7eecba54b 100644 --- a/core/lib/mno_enterprise/concerns/models/ability.rb +++ b/core/lib/mno_enterprise/concerns/models/ability.rb @@ -25,18 +25,16 @@ def initialize(user) #=================================================== # Organization #=================================================== - can :create, MnoEnterprise::Organization + can :create, MnoEnterprise::OrgaRelation - can :read, MnoEnterprise::Organization do |organization| - !!user.role(organization) + can :read, MnoEnterprise::OrgaRelation do |orga_relation| + !!orga_relation end - can [:update, :destroy, :manage_billing], MnoEnterprise::Organization do |organization| - user.role(organization) == 'Super Admin' + can [:update, :destroy, :manage_billing], MnoEnterprise::OrgaRelation do |orga_relation| + orga_relation&.role == 'Super Admin' end - - # TODO: replace by organization_id, no need to load a full organization, and make user.role accept a string can [:upload, :purchase, @@ -44,12 +42,12 @@ def initialize(user) :administrate, :manage_app_instances, :manage_teams], MnoEnterprise::OrgaRelation do |orga_relation| - ['Super Admin','Admin'].include? orga_relation.role + orga_relation && ['Super Admin', 'Admin'].include?(orga_relation.role) end # To be updated # TODO: replace by organization_id, no need to load a full organization - can :sync_apps, MnoEnterprise::OrgaRelation |orga_relation| + can :sync_apps, MnoEnterprise::OrgaRelation do |orga_relation| !!orga_relation end @@ -63,12 +61,14 @@ def initialize(user) # AppInstance #=================================================== can :access, MnoEnterprise::AppInstance do |app_instance| - role = user.role_from_id(app_instance.owner_id) - !!role && ( - ['Super Admin','Admin'].include?(role) || - user.teams.empty? || - user.teams.map(&:app_instances).compact.flatten.map(&:id).include?(app_instance.id) - ) + orga_relation = MnoEnterprise::OrgaRelation.where('user.id': user.id, 'organization.id': app_instance.owner_id).first + role = orga_relation&.role + if role && ['Super Admin', 'Admin'].include?(role) + true + else + teams = MnoEnterprise::Team.where('users.id': user.id).includes(:app_instances).with_params(fields: { app_instances: 'id' }) + teams.empty? || teams.map(&:app_instances).compact.flatten.map(&:id).include?(app_instance.id) + end end #=================================================== @@ -112,15 +112,15 @@ def initialize(user) def impac_abilities(user) can :manage_impac, MnoEnterprise::Dashboard do |dhb| dhb.organizations.any? && dhb.organizations.all? do |org| - !!user.role(org) && ['Super Admin', 'Admin'].include?(user.role(org)) + role = orga_relation(user.id, org.id)&.role + role && ['Super Admin', 'Admin'].include?(role) end end can :manage_dashboard, MnoEnterprise::Dashboard do |dashboard| - if dashboard.owner_type == "Organization" + if dashboard.owner_type == 'Organization' # The current user is a member of the organization that owns the dashboard that has the kpi attached to - owner = MnoEnterprise::Organization.find(dashboard.owner_id) - owner && !!user.role(owner) + !!orga_relation(user, dashboard.owner_id) elsif dashboard.owner_type == "User" # The current user is the owner of the dashboard that has the kpi attached to dashboard.owner_id == user.id diff --git a/core/lib/mno_enterprise/concerns/models/app_instance.rb b/core/lib/mno_enterprise/concerns/models/app_instance.rb index ca7b466b8..50f822967 100644 --- a/core/lib/mno_enterprise/concerns/models/app_instance.rb +++ b/core/lib/mno_enterprise/concerns/models/app_instance.rb @@ -28,7 +28,8 @@ module MnoEnterprise::Concerns::Models::AppInstance # Class methods #================================================================== module ClassMethods - def provision!(input) + def provision!(app_nid, owner_id, owner_type) + input = { data: { attributes: { app_nid: app_nid, owner_id: owner_id, owner_type: owner_type} } } result = provision(input) process_custom_result(result) end @@ -49,7 +50,7 @@ def to_audit_event uid: uid, name: name, app_nid: app_nid, - organization_id: owner_id + organization_id: owner.id } end diff --git a/core/lib/mno_enterprise/testing_support/factories/product_pricing.rb b/core/lib/mno_enterprise/testing_support/factories/product_pricing.rb index 04a46f0a8..97290272f 100644 --- a/core/lib/mno_enterprise/testing_support/factories/product_pricing.rb +++ b/core/lib/mno_enterprise/testing_support/factories/product_pricing.rb @@ -14,6 +14,6 @@ per_unit "per unit" prices {[]} external_id "external id" - product_id 1 + product { build(:product) } end end diff --git a/core/lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb b/core/lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb index 8fc3081bc..c8825babd 100644 --- a/core/lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb +++ b/core/lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb @@ -8,7 +8,11 @@ module MnoEnterpriseApiTestHelper basic_auth: [MnoEnterprise.tenant_id, MnoEnterprise.tenant_key] } - JSON_API_RESULT_HEADERS = {content_type: 'application/vnd.api+json'} + JSON_API_RESULT_HEADERS = { content_type: 'application/vnd.api+json' } + + def one_page + { number: 1, size: 1 } + end def serialize_type(res) case @@ -16,13 +20,13 @@ def serialize_type(res) return res.map { |e| serialize_type(e) } when res.kind_of?(MnoEnterprise::BaseResource) hash = res.attributes.dup - hash.each do |k,v| + hash.each do |k, v| hash[k] = serialize_type(v) end return hash when res.kind_of?(Hash) hash = res.dup - hash.each do |k,v| + hash.each do |k, v| hash[k] = serialize_type(v) end return hash @@ -50,8 +54,23 @@ def stub_audit_events stub_api_v2(:post, '/audit_events') end - def stub_user(user) - stub_api_v2(:get, "/users/#{user.id}", user, %i(deletion_requests organizations orga_relations dashboards teams sub_tenant)) + def stub_user(user, included = [], params = {}) + stub_api_v2(:get, "/users/#{user.id}", user, included, params) + end + + def stub_orga_relation(user, organization, orga_relation, id_field = 'id') + filter = { 'user.id': user.id, "organization.#{id_field}": organization.public_send(id_field) } + stub_api_v2(:get, '/orga_relations', [orga_relation].compact, [], { filter: filter, page: one_page }) + end + + def stub_deletion_requests(user, deletion_requests) + filter = { + 'created_at.gt': MnoEnterprise::DeletionRequest::EXPIRATION_TIME.minutes.ago, + 'deletable.id': user.id, + 'deletable.type': 'users', + 'status.ne': 'cancelled' + } + stub_api_v2(:get, '/deletion_requests', deletion_requests, [], { filter: filter, page: one_page, sort: '-created_at' }) end def api_v2_url(suffix, included = [], params = {}) @@ -141,7 +160,7 @@ def serialize_data(entity, included, included_entities) def from_apiv2(entity, included) included_entities = {} data = if entity.kind_of?(Array) - entity.map{|e| serialize_data(e, included, included_entities)} + entity.map { |e| serialize_data(e, included, included_entities) } else serialize_data(entity, included, included_entities) end diff --git a/core/spec/models/mno_enterprise/ability_spec.rb b/core/spec/models/mno_enterprise/ability_spec.rb index f742a2510..5a7b5bb56 100644 --- a/core/spec/models/mno_enterprise/ability_spec.rb +++ b/core/spec/models/mno_enterprise/ability_spec.rb @@ -4,23 +4,20 @@ # TODO: add more ability tests RSpec.describe MnoEnterprise::Ability, type: :model do subject(:ability) { described_class.new(user) } - let(:user) { FactoryGirl.build(:user, admin_role: admin_role) } + let(:user) { build(:user, admin_role: admin_role) } let(:admin_role) { nil } - let(:organization) { FactoryGirl.build(:organization) } - - before { allow(user).to receive(:role).with(organization) { nil } } - + let(:orga_relation) { build(:orga_relation, role: 'Member') } context 'when User#admin_role is admin' do let(:admin_role) { 'admin' } - it { is_expected.to be_able_to(:manage_app_instances, organization) } + it { is_expected.to be_able_to(:manage_app_instances, orga_relation) } end context 'when User#admin_role has a random case' do let(:admin_role) { 'ADmIn' } - it { is_expected.to be_able_to(:manage_app_instances, organization) } + it { is_expected.to be_able_to(:manage_app_instances, orga_relation) } end context 'when no User#admin_role' do - it { is_expected.not_to be_able_to(:manage_app_instances, organization) } + it { is_expected.not_to be_able_to(:manage_app_instances, orga_relation) } end end From 96f265a29e43eb0d59967d4ea08af7076b8e31d9 Mon Sep 17 00:00:00 2001 From: x4d3 Date: Wed, 15 Nov 2017 11:34:48 +0000 Subject: [PATCH 04/10] Fix 'user.ids' -> 'users.id' --- .../admin/impac/dashboard_templates_controller.rb | 2 +- .../jpi/v1/impac/dashboard_templates_controller.rb | 2 +- .../jpi/v1/impac/dashboards_controller.rb | 10 +++++----- .../controllers/jpi/v1/impac/widgets_controller.rb | 2 +- .../controllers/jpi/v1/subscriptions_controller.rb | 8 ++++---- .../impac/dashboard_templates_controller_spec.rb | 2 +- .../impac/dashboard_templates_controller_spec.rb | 2 +- .../jpi/v1/impac/dashboards_controller_spec.rb | 2 +- .../jpi/v1/impac/widgets_controller_spec.rb | 2 +- .../jpi/v1/subscriptions_controller_spec.rb | 14 +++++++------- 10 files changed, 23 insertions(+), 23 deletions(-) diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb index 31d600394..298d91b5d 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb @@ -59,7 +59,7 @@ def destroy private def load_organizations - @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) + @organizations = MnoEnterprise::Organization.where('users.id': current_user.id) end def whitelisted_params diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboard_templates_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboard_templates_controller.rb index 0e58f3f5e..46086de0f 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboard_templates_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboard_templates_controller.rb @@ -17,6 +17,6 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::DashboardTemplatesC # GET /mnoe/jpi/v1/impac/dashboard_templates def index @templates = MnoEnterprise::Dashboard.published_templates.includes(*DASHBOARD_DEPENDENCIES) - @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) + @organizations = MnoEnterprise::Organization.where('users.id': current_user.id) end end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb index 57ca7e956..0b7995a43 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/dashboards_controller.rb @@ -18,13 +18,13 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::DashboardsControlle # GET /mnoe/jpi/v1/impac/dashboards def index dashboards - @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) + @organizations = MnoEnterprise::Organization.where('users.id': current_user.id) end # GET /mnoe/jpi/v1/impac/dashboards/1 # -> GET /api/mnoe/v1/users/1/dashboards def show - @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) + @organizations = MnoEnterprise::Organization.where('users.id': current_user.id) render_not_found('dashboard') unless dashboard(*DASHBOARD_DEPENDENCIES) end @@ -37,7 +37,7 @@ def create @dashboard = MnoEnterprise::Dashboard.create!(dashboard_create_params) MnoEnterprise::EventLogger.info('dashboard_create', current_user.id, 'Dashboard Creation', @dashboard) @dashboard = dashboard.load_required(*DASHBOARD_DEPENDENCIES) - @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) + @organizations = MnoEnterprise::Organization.where('users.id': current_user.id) render 'show' end @@ -49,7 +49,7 @@ def update # TODO: enable authorization # authorize! :manage_dashboard, dashboard dashboard.update_attributes!(dashboard_update_params) - @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) + @organizations = MnoEnterprise::Organization.where('users.id': current_user.id) # Reload Dashboard @dashboard = dashboard.load_required(DASHBOARD_DEPENDENCIES) render 'show' @@ -76,7 +76,7 @@ def copy # Owner is the current user by default, can be overriden to something else (eg: current organization) @dashboard = template.copy!(current_user, dashboard_params[:name], dashboard_params[:organization_ids]) @dashboard = @dashboard.load_required(DASHBOARD_DEPENDENCIES) - @organizations = MnoEnterprise::Organization.where('user.ids': current_user.id) + @organizations = MnoEnterprise::Organization.where('users.id': current_user.id) render 'show' end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/widgets_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/widgets_controller.rb index 868759e2d..3a6a78510 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/widgets_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/impac/widgets_controller.rb @@ -17,7 +17,7 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Impac::WidgetsController # -> GET /api/mnoe/v1/organizations/:id/widgets def index render_not_found('organization') unless parent_organization - @widgets = MnoEnterprise::Widget.find(organization_id: parent_organization_id) + @widgets = MnoEnterprise::Widget.find('organization.id': parent_organization.id) end # POST /mnoe/jpi/v1/impac/dashboards/:id/widgets diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscriptions_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscriptions_controller.rb index ebd9584de..df633a059 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscriptions_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/subscriptions_controller.rb @@ -42,7 +42,7 @@ def create def update authorize! :manage_app_instances, orga_relation - subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization_id, id: params[:id]).first + subscription = MnoEnterprise::Subscription.where('organization.id': parent_organization_id, id: params[:id]).first return render_not_found('subscription') unless subscription if params[:subscription][:product_pricing_id] subscription.relationships.product_pricing = MnoEnterprise::ProductPricing.new(id: params[:subscription][:product_pricing_id]) @@ -63,7 +63,7 @@ def update def cancel authorize! :manage_app_instances, orga_relation - subscription = MnoEnterprise::Subscription.where(organization_id: parent_organization_id, id: params[:id]).first + subscription = MnoEnterprise::Subscription.where('organization.id': parent_organization_id, id: params[:id]).first return render_not_found('subscription') unless subscription subscription.cancel! @@ -84,11 +84,11 @@ def subscription_update_params def fetch_subscriptions(organization_id) query = MnoEnterprise::Subscription.with_params(_metadata: { organization_id: organization_id }) - MnoEnterprise::Subscription.fetch_all(query.includes(*SUBSCRIPTION_INCLUDES).where(organization_id: organization_id)) + MnoEnterprise::Subscription.fetch_all(query.includes(*SUBSCRIPTION_INCLUDES).where('organization.id': organization_id)) end def fetch_subscription(organization_id, id) query = MnoEnterprise::Subscription.with_params(_metadata: { organization_id: organization_id }) - query.includes(*SUBSCRIPTION_INCLUDES).where(organization_id: organization_id, id: id).first + query.includes(*SUBSCRIPTION_INCLUDES).where('organization.id': organization_id, id: id).first end end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller_spec.rb index c2a1552e0..627f27271 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller_spec.rb @@ -71,7 +71,7 @@ def hash_for_kpi(kpi) before do stub_user(user) sign_in user - stub_api_v2(:get, '/organizations', [organization], [], filter: { 'user.ids': user.id }) + stub_api_v2(:get, '/organizations', [organization], [], filter: { 'users.id': user.id }) stub_audit_events end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboard_templates_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboard_templates_controller_spec.rb index b4e78b113..e4050f902 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboard_templates_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboard_templates_controller_spec.rb @@ -72,7 +72,7 @@ def hash_for_kpi(kpi) subject { get :index } before do - stub_api_v2(:get, '/organizations', [organization], [], filter: { 'user.ids': user.id}) + stub_api_v2(:get, '/organizations', [organization], [], filter: { 'users.id': user.id}) stub_api_v2(:get, '/dashboards', [template], dashboard_dependencies, filter: { dashboard_type: 'template', published: true}) end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboards_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboards_controller_spec.rb index e55adafc5..4b5dcdda8 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboards_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/impac/dashboards_controller_spec.rb @@ -85,7 +85,7 @@ def hash_for_kpi(kpi) before do sign_in user stub_audit_events - stub_api_v2(:get, '/organizations', [organization], [], filter: { 'user.ids': user.id}) + stub_api_v2(:get, '/organizations', [organization], [], filter: { 'users.id': user.id}) end describe 'GET #index' do diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/impac/widgets_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/impac/widgets_controller_spec.rb index 8eb5e7fab..f5544ecee 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/impac/widgets_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/impac/widgets_controller_spec.rb @@ -27,7 +27,7 @@ module MnoEnterprise subject { get :index, organization_id: organization.uid } before { stub_api_v2(:get, '/organizations', [organization], [], { filter: { uid: organization.uid } }) } - before { stub_api_v2(:get, '/widgets', [widget], [], { filter: { organization_id: organization.id } }) } + before { stub_api_v2(:get, '/widgets', [widget], [], { filter: { 'organization.id': organization.id } }) } it 'returns the widgets' do subject expect(JSON.parse(response.body)).to eq({ 'widgets' => [ diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/subscriptions_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/subscriptions_controller_spec.rb index 801f85aae..a0b6164ac 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/subscriptions_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/subscriptions_controller_spec.rb @@ -32,7 +32,7 @@ module MnoEnterprise describe 'GET #index' do let(:subscription) { build(:subscription) } - before { stub_api_v2(:get, "/subscriptions", [subscription], [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {organization_id: organization.id}, '_metadata[organization_id]' => organization.id}) } + before { stub_api_v2(:get, "/subscriptions", [subscription], [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {'organization.id': organization.id}, '_metadata[organization_id]' => organization.id}) } before { sign_in user } subject { get :index, organization_id: organization.id } @@ -43,7 +43,7 @@ module MnoEnterprise describe 'GET #show' do let(:subscription) { build(:subscription) } - before { stub_api_v2(:get, "/subscriptions", subscription, [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {organization_id: organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1, '_metadata[organization_id]' => organization.id}) } + before { stub_api_v2(:get, "/subscriptions", subscription, [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {'organization.id': organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1, '_metadata[organization_id]' => organization.id}) } before { sign_in user } subject { get :show, organization_id: organization.id, id: subscription.id } @@ -58,7 +58,7 @@ module MnoEnterprise before { stub_audit_events } before { stub_api_v2(:post, "/subscriptions", subscription, [], {}) } - before { stub_api_v2(:get, "/subscriptions", subscription, [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {organization_id: organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1, '_metadata[organization_id]' => organization.id}) } + before { stub_api_v2(:get, "/subscriptions", subscription, [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {'organization.id': organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1, '_metadata[organization_id]' => organization.id}) } before { sign_in user } subject { post :create, organization_id: organization.id, subscription: {custom_data: {foo: :bar}.to_json, product_pricing_id: product_pricing.id} } @@ -91,8 +91,8 @@ module MnoEnterprise before { stub_audit_events } before { stub_api_v2(:post, "/subscriptions/#{subscription.id}/modify", subscription, [], {}) } - before { stub_api_v2(:get, "/subscriptions", subscription, [], {filter: {organization_id: organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1}) } - before { stub_api_v2(:get, "/subscriptions", subscription, [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {organization_id: organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1, '_metadata[organization_id]' => organization.id}) } + before { stub_api_v2(:get, "/subscriptions", subscription, [], {filter: {'organization.id': organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1}) } + before { stub_api_v2(:get, "/subscriptions", subscription, [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {'organization.id': organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1, '_metadata[organization_id]' => organization.id}) } before { sign_in user } subject { put :update, organization_id: organization.id, id: subscription.id, subscription: {custom_data: {foo: :bar}.to_json, product_pricing_id: product_pricing.id} } @@ -124,8 +124,8 @@ module MnoEnterprise before { stub_audit_events } before { stub_api_v2(:post, "/subscriptions/#{subscription.id}/cancel", subscription, [], {}) } - before { stub_api_v2(:get, "/subscriptions", subscription, [], {filter: {organization_id: organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1}) } - before { stub_api_v2(:get, "/subscriptions", subscription, [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {organization_id: organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1, '_metadata[organization_id]' => organization.id}) } + before { stub_api_v2(:get, "/subscriptions", subscription, [], {filter: {'organization.id': organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1}) } + before { stub_api_v2(:get, "/subscriptions", subscription, [:'product_pricing.product', :product_contract, :organization, :user, :'license_assignments.user', :'product_instance.product'], {filter: {'organization.id': organization.id, id: subscription.id}, 'page[number]' => 1, 'page[size]' => 1, '_metadata[organization_id]' => organization.id}) } before { sign_in user } subject { post :cancel, organization_id: organization.id, id: subscription.id } From bfdb4304e34cd8034193226f22d8a88d8acf8829 Mon Sep 17 00:00:00 2001 From: x4d3 Date: Wed, 15 Nov 2017 14:45:53 +0000 Subject: [PATCH 05/10] Add only needed fields for users --- .../jpi/v1/admin/users_controller.rb | 22 ++++++++++++------- .../jpi/v1/admin/users_controller_spec.rb | 11 ++++++++-- .../has_one_extension.rb | 6 +++-- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/users_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/users_controller.rb index f88194735..0e22c6789 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/users_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/users_controller.rb @@ -1,6 +1,8 @@ module MnoEnterprise class Jpi::V1::Admin::UsersController < Jpi::V1::Admin::BaseResourceController + INCLUDED_FIELDS = [:id, :uid, :email, :phone, :name, :surname, :admin_role, :created_at, :updated_at, :confirmed_at, :last_sign_in_at, :sign_in_count, :user_access_requests, :organizations, :sub_tenant] + # GET /mnoe/jpi/v1/admin/users def index if params[:terms] @@ -10,21 +12,24 @@ def index @users = @users | MnoEnterprise::User .apply_query_params(params.except(:terms)) .with_params(_metadata: { act_as_manager: current_user.id }) + .select(INCLUDED_FIELDS) .includes(:user_access_requests, :sub_tenant) .where(Hash[*t]) end # Ensure that no duplicates are returned as a result of multiple terms being applied to search query # ex. user.name = "John" and user.email = "john.doe@example.com" would return a duplicate when searching for "john" - @users.uniq!{ |u| u.id } + @users.uniq! { |u| u.id } response.headers['X-Total-Count'] = @users.count else # Index mode query = MnoEnterprise::User - .apply_query_params(params) - .with_params(_metadata: { act_as_manager: current_user.id }) - .includes(:user_access_requests, :sub_tenant) + .apply_query_params(params) + .with_params(_metadata: { act_as_manager: current_user.id }) + .select(INCLUDED_FIELDS) + .includes(:user_access_requests, :sub_tenant) + @users = query.to_a response.headers['X-Total-Count'] = query.meta.record_count end @@ -33,9 +38,10 @@ def index # GET /mnoe/jpi/v1/admin/users/1 def show @user = MnoEnterprise::User.with_params(_metadata: { act_as_manager: current_user.id }) - .includes(:orga_relations, :organizations, :user_access_requests, :sub_tenant) - .find(params[:id]) - .first + .includes(:orga_relations, :organizations, :user_access_requests, :sub_tenant) + .select(INCLUDED_FIELDS) + .find(params[:id]) + .first @user_organizations = @user.organizations end @@ -73,7 +79,7 @@ def update_clients @user = MnoEnterprise::User.with_params(_metadata: { act_as_manager: current_user.id }).find(params[:id]).first return render_not_found('User') unless @user attributes = params.require(:user).permit(add: [], remove: []) - @user.update_clients!({data: {attributes: attributes}}) + @user.update_clients!({ data: { attributes: attributes } }) @user = @user.load_required(:sub_tenant) render :show end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/users_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/users_controller_spec.rb index c0242c25a..ea3a1268a 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/users_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/users_controller_spec.rb @@ -14,6 +14,13 @@ module MnoEnterprise let(:current_user) { build(:user, :admin) } let!(:current_user_stub) { stub_user(current_user) } + let(:select_fields) do + { + users: Jpi::V1::Admin::UsersController::INCLUDED_FIELDS.join(',') + } + end + + # Stub user and user call let(:user) { build(:user) } @@ -27,7 +34,7 @@ module MnoEnterprise let(:data) { JSON.parse(response.body) } - before { stub_api_v2(:get, "/users", [user], [:user_access_requests, :sub_tenant], { _metadata: { act_as_manager: current_user.id } }) } + before { stub_api_v2(:get, "/users", [user], [:user_access_requests, :sub_tenant], {fields: select_fields, _metadata: { act_as_manager: current_user.id } }) } before { subject } it { expect(data['users'].first['id']).to eq(user.id) } @@ -39,7 +46,7 @@ module MnoEnterprise let(:data) { JSON.parse(response.body) } let(:included) { [:orga_relations, :organizations, :user_access_requests, :sub_tenant] } - before { stub_api_v2(:get, "/users/#{user.id}", user, included, { _metadata: { act_as_manager: current_user.id } }) } + before { stub_api_v2(:get, "/users/#{user.id}", user, included, {fields: select_fields, _metadata: { act_as_manager: current_user.id } }) } before { subject } it { expect(data['user']['id']).to eq(user.id) } diff --git a/core/lib/json_api_client_extension/has_one_extension.rb b/core/lib/json_api_client_extension/has_one_extension.rb index e02ad0e72..18156614e 100644 --- a/core/lib/json_api_client_extension/has_one_extension.rb +++ b/core/lib/json_api_client_extension/has_one_extension.rb @@ -5,11 +5,13 @@ module JsonApiClientExtension::HasOneExtension def has_one(attr_name, options = {}) class_eval <<-CODE def #{attr_name}_id=(id) - ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id Use relationships instead") + # Uncomment when doing refactoring + # ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id= Use relationships instead") super end def #{attr_name}_id - ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id Use relationships instead") + # Uncomment when doing refactoringgit + # ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id Use relationships instead") super end def #{attr_name}=(relation) From 05a08bf9b4ec1208b05b54fbfa40bc4265cedf56 Mon Sep 17 00:00:00 2001 From: x4d3 Date: Wed, 15 Nov 2017 14:49:26 +0000 Subject: [PATCH 06/10] Moved common method to application_controller --- .../jpi/v1/base_resource_controller.rb | 13 ------------- .../jpi/v1/admin/base_resource_controller.rb | 12 ------------ .../mno_enterprise/application_controller.rb | 13 +++++++++++++ 3 files changed, 13 insertions(+), 25 deletions(-) diff --git a/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb index 67d1e78d5..93ffc3bf3 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb @@ -16,18 +16,5 @@ def check_authorization end true end - - def render_not_found(resource, id = params[:id]) - render json: { errors: { message: "#{resource.titleize} not found (id=#{id})", code: 404, params: params } }, status: :not_found - end - - def render_bad_request(attempted_action, issue) - issue = issue.full_messages if issue.respond_to?(:full_messages) - render json: { errors: { message: "Error while trying to #{attempted_action}: #{issue}", code: 400, params: params } }, status: :bad_request - end - - def render_forbidden_request(attempted_action) - render json: { errors: { message: "Error while trying to #{attempted_action}: you do not have permission", code: 403 } }, status: :forbidden - end end end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb index 2fa9f32d1..de5b30625 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb @@ -22,16 +22,4 @@ def check_authorization render nothing: true, status: :unauthorized false end - - def render_not_found(resource = controller_name.singularize, id = params[:id]) - render json: { errors: { message: "#{resource.titleize} not found (id=#{id})", code: 404, params: params } }, status: :not_found - end - - def render_bad_request(attempted_action, issue) - render json: { errors: { message: "Error while trying to #{attempted_action}: #{issue}", code: 400, params: params } }, status: :bad_request - end - - def render_forbidden_request(attempted_action) - render json: { errors: { message: "Error while trying to #{attempted_action}: you do not have permission", code: 403 } }, status: :forbidden - end end diff --git a/core/app/controllers/mno_enterprise/application_controller.rb b/core/app/controllers/mno_enterprise/application_controller.rb index 86680b12f..3ab4d8bdc 100644 --- a/core/app/controllers/mno_enterprise/application_controller.rb +++ b/core/app/controllers/mno_enterprise/application_controller.rb @@ -173,6 +173,19 @@ def orga_relation end end + def render_not_found(resource, id = params[:id]) + render json: { errors: { message: "#{resource.titleize} not found (id=#{id})", code: 404, params: params } }, status: :not_found + end + + def render_bad_request(attempted_action, issue) + issue = issue.full_messages if issue.respond_to?(:full_messages) + render json: { errors: { message: "Error while trying to #{attempted_action}: #{issue}", code: 400, params: params } }, status: :bad_request + end + + def render_forbidden_request(attempted_action) + render json: { errors: { message: "Error while trying to #{attempted_action}: you do not have permission", code: 403 } }, status: :forbidden + end + private # Append params to the fragment part of an existing url String From a4b6982481a1498889561bd0ba29a9494f33f1a1 Mon Sep 17 00:00:00 2001 From: x4d3 Date: Wed, 15 Nov 2017 15:08:54 +0000 Subject: [PATCH 07/10] Moved common method back to base_resource --- .../jpi/v1/base_resource_controller.rb | 32 +++++++++++++++++++ .../jpi/v1/admin/base_resource_controller.rb | 1 - .../jpi/v1/marketplace_controller.rb | 5 +++ .../controllers/provision_controller.rb | 2 +- .../mno_enterprise/application_controller.rb | 31 ------------------ 5 files changed, 38 insertions(+), 33 deletions(-) diff --git a/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb index 93ffc3bf3..5f2c7900a 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/base_resource_controller.rb @@ -3,6 +3,38 @@ class Jpi::V1::BaseResourceController < ApplicationController before_filter :check_authorization protected + + # test if the provided argument is a id or an uid + # @param [Object] id or uid + def is_id?(string) + string.to_i.to_s == string + end + + def parent_organization_id + id_or_uid = params[:organization_id] + if is_id?(id_or_uid) + id_or_uid + else + parent_organization.id + end + end + + def parent_organization + @parent_organization ||= begin + id_or_uid = params[:organization_id] + query = is_id?(id_or_uid) ? id_or_uid : { uid: id_or_uid } + MnoEnterprise::Organization.find(query).first + end + end + + def orga_relation + @orga_relation ||= begin + id_or_uid = params[:organization_id] + organization_field = is_id?(id_or_uid) ? 'id' : 'uid' + MnoEnterprise::OrgaRelation.where('user.id' => current_user.id, "organization.#{organization_field}" => id_or_uid).first + end + end + # Check current user is logged in # Check organization is valid if specified def check_authorization diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb index de5b30625..69f57aec7 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/admin/base_resource_controller.rb @@ -12,7 +12,6 @@ module MnoEnterprise::Concerns::Controllers::Jpi::V1::Admin::BaseResourceControl end protected - # Check current user is logged in # Check organization is valid if specified def check_authorization diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb index c571a82d0..359a19d67 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb @@ -63,4 +63,9 @@ def app_relation(org_id = nil) def app_instance_organization_id return params[:organization_id] if current_user && params[:organization_id].presence && orga_relation end + + def orga_relation + MnoEnterprise::OrgaRelation.where('user.id' => current_user.id, 'organization.id': params[:organization_id]).first + end + end diff --git a/api/lib/mno_enterprise/concerns/controllers/provision_controller.rb b/api/lib/mno_enterprise/concerns/controllers/provision_controller.rb index 38a43e6cb..ae68b8de5 100644 --- a/api/lib/mno_enterprise/concerns/controllers/provision_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/provision_controller.rb @@ -67,7 +67,7 @@ def create app_instances = [] params[:apps].each do |product_name| - app_instance = MnoEnterprise::AppInstance.provision!(product_name, parent_organization_id, 'Organization' ) + app_instance = MnoEnterprise::AppInstance.provision!(product_name, params[:organization_id], 'Organization' ) app_instance = app_instance.load_required(:owner) app_instances << app_instance MnoEnterprise::EventLogger.info('app_add', current_user.id, 'App added', app_instance) diff --git a/core/app/controllers/mno_enterprise/application_controller.rb b/core/app/controllers/mno_enterprise/application_controller.rb index 3ab4d8bdc..72446da01 100644 --- a/core/app/controllers/mno_enterprise/application_controller.rb +++ b/core/app/controllers/mno_enterprise/application_controller.rb @@ -142,37 +142,6 @@ def after_sign_out_path_for(resource_or_scope) # Helper methods #============================================ - # test if the provided argument is a id or an uid - # @param [Object] id or uid - def is_id?(string) - string.to_i.to_s == string - end - - def parent_organization_id - id_or_uid = params[:organization_id] - if is_id?(id_or_uid) - id_or_uid - else - parent_organization.id - end - end - - def parent_organization - @parent_organization ||= begin - id_or_uid = params[:organization_id] - query = is_id?(id_or_uid) ? id_or_uid : { uid: id_or_uid } - MnoEnterprise::Organization.find(query).first - end - end - - def orga_relation - @orga_relation ||= begin - id_or_uid = params[:organization_id] - organization_field = is_id?(id_or_uid) ? 'id' : 'uid' - MnoEnterprise::OrgaRelation.where('user.id' => current_user.id, "organization.#{organization_field}" => id_or_uid).first - end - end - def render_not_found(resource, id = params[:id]) render json: { errors: { message: "#{resource.titleize} not found (id=#{id})", code: 404, params: params } }, status: :not_found end From eadf81cfccd4dba808bccde98e040a14bfe71274 Mon Sep 17 00:00:00 2001 From: x4d3 Date: Wed, 22 Nov 2017 15:09:18 +0000 Subject: [PATCH 08/10] Do not load_organizations in before_action --- .../jpi/v1/admin/impac/dashboard_templates_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb index 298d91b5d..3a83e72c2 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb @@ -1,8 +1,6 @@ module MnoEnterprise class Jpi::V1::Admin::Impac::DashboardTemplatesController < Jpi::V1::Admin::BaseResourceController - before_action :load_organizations, except: [:destroy] - # TODO [APIV2]: [:'widgets.kpis', :'kpis.alerts'] DASHBOARD_DEPENDENCIES = [:widgets, :kpis] @@ -36,6 +34,7 @@ def create @dashboard_template.save! MnoEnterprise::EventLogger.info('dashboard_template_create', current_user.id, 'Dashboard Template Creation', @dashboard_template) @dashboard_template = @dashboard_template.load_required(*DASHBOARD_DEPENDENCIES) + load_organizations render 'show' end @@ -45,6 +44,7 @@ def update dashboard_template.update!(dashboard_template_params) @dashboard_template = @dashboard_template.load_required(*DASHBOARD_DEPENDENCIES) MnoEnterprise::EventLogger.info('dashboard_template_update', current_user.id, 'Dashboard Template Update', @dashboard_template) + load_organizations render 'show' end From 76edb0023895b50b9370d4c319ba3e0d514f7081 Mon Sep 17 00:00:00 2001 From: x4d3 Date: Wed, 22 Nov 2017 16:50:27 +0000 Subject: [PATCH 09/10] Apply code review comments - fix issue with provisioning + update spec - Add log warning in has_one in test and development --- .../jpi/v1/admin/impac/dashboard_templates_controller.rb | 1 + .../jpi/v1/admin/organizations_controller.rb | 4 +++- .../controllers/jpi/v1/marketplace_controller.rb | 7 +++---- .../jpi/v1/admin/organizations_controller_spec.rb | 6 +++--- .../mno_enterprise/jpi/v1/marketplace_controller_spec.rb | 3 ++- core/lib/json_api_client_extension/has_one_extension.rb | 9 ++++----- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb index 3a83e72c2..1921fa06b 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/impac/dashboard_templates_controller.rb @@ -26,6 +26,7 @@ def index # GET /mnoe/jpi/v1/admin/impac/dashboard_templates/1 def show @dashboard_template = MnoEnterprise::Dashboard.find_one!(params[:id], *DASHBOARD_DEPENDENCIES) + load_organizations end # POST /mnoe/jpi/v1/admin/impac/dashboard_templates diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/organizations_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/organizations_controller.rb index 9d3f96f51..e614005ce 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/organizations_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/organizations_controller.rb @@ -210,7 +210,9 @@ def update_app_list if params[:organization].key?(:app_nids) && (desired_nids = Array(params[:organization][:app_nids])) existing_apps = @organization.app_instances&.select(&:active?) || [] existing_apps.each { |app_instance| desired_nids.delete(app_instance.app.nid) || app_instance.terminate } - desired_nids.each { |nid| @organization.provision_app_instance!(nid) } + desired_nids.each do |nid| + MnoEnterprise::AppInstance.provision!(nid, @organization.id, 'Organization' ) + end end end end diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb index 359a19d67..4c9fa8826 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/marketplace_controller.rb @@ -61,11 +61,10 @@ def app_relation(org_id = nil) # Return the organization_id passed as query parameters if the current_user has access to it def app_instance_organization_id - return params[:organization_id] if current_user && params[:organization_id].presence && orga_relation + return params[:organization_id] if current_user && params[:organization_id].presence && orga_relation_id end - def orga_relation - MnoEnterprise::OrgaRelation.where('user.id' => current_user.id, 'organization.id': params[:organization_id]).first + def orga_relation_id + MnoEnterprise::OrgaRelation.where('user.id': current_user.id, 'organization.id': params[:organization_id]).select(:id).first&.id end - end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb index 341aecd58..55066aa35 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb @@ -110,10 +110,10 @@ module MnoEnterprise describe 'app provisioning' do let(:params) { attributes_for(:organization).merge(app_nids: ['xero', app_instance.app.nid]) } - - before { expect_any_instance_of(Organization).to receive(:provision_app_instance!) } + let!(:provisionning_stub) { stub_api_v2(:post, '/app_instances/provision')} before { subject } it { expect(data['organization']['id']).to eq(organization.id) } + it { expect(provisionning_stub).to have_been_requested } end end @@ -130,7 +130,7 @@ module MnoEnterprise let(:orga_invite) { build(:orga_invite) } before { allow(orga_invite).to receive(:user).and_return(invited_user) } - before { stub_api_v2(:get, '/users', invited_user, [:orga_relations], { filter: { email: params[:email] }, page: { number: 1, size: 1 } }) } + before { stub_api_v2(:get, '/users', invited_user, [:orga_relations], { filter: { email: params[:email] }, page: one_page }) } before { stub_api_v2(:get, "/orga_invites/#{orga_invite.id}", orga_invite, [:user]) } before { expect(MnoEnterprise::OrgaInvite).to receive(:create).and_return(orga_invite) } before { subject } diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb index 4e78a5588..7c98a4b77 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/marketplace_controller_spec.rb @@ -133,7 +133,8 @@ def hash_for_apps(apps) before do sign_in(user) stub_api_v2(:get, "/organizations", [organization], [], { fields: { organizations: 'id' }, filter: { id: organization.id, 'users.id' => user.id }, page: one_page }) - stub_orga_relation(user, organization, orga_relation) + stub_api_v2(:get, '/orga_relations', [orga_relation], [], { fields: { orga_relations: 'id' }, filter: { 'user.id': user.id, 'organization.id': organization.id }, page: one_page }) + stub_api_v2(:get, '/apps', [app], DEPENDENCIES, { _metadata: { organization_id: organization.id }, filter: { active: true } }) stub_api_v2(:get, '/apps', [app], [], { diff --git a/core/lib/json_api_client_extension/has_one_extension.rb b/core/lib/json_api_client_extension/has_one_extension.rb index 18156614e..b1d3e922c 100644 --- a/core/lib/json_api_client_extension/has_one_extension.rb +++ b/core/lib/json_api_client_extension/has_one_extension.rb @@ -3,15 +3,15 @@ module JsonApiClientExtension::HasOneExtension class_methods do def has_one(attr_name, options = {}) + setter_log_warning = (Rails.env.test? || Rails.env.development?) ? "ActiveSupport::Deprecation.warn('#{self.name}.#{attr_name}_id= Use relationships instead')" : '' + getter_log_warning = (Rails.env.test? || Rails.env.development?) ? "ActiveSupport::Deprecation.warn('#{self.name}.#{attr_name}_id Use relationships instead')" : '' class_eval <<-CODE def #{attr_name}_id=(id) - # Uncomment when doing refactoring - # ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id= Use relationships instead") + #{setter_log_warning} super end def #{attr_name}_id - # Uncomment when doing refactoringgit - # ActiveSupport::Deprecation.warn(self.class.name + ".#{attr_name}_id Use relationships instead") + #{getter_log_warning} super end def #{attr_name}=(relation) @@ -21,7 +21,6 @@ def #{attr_name}=(relation) def #{attr_name} relations[:#{attr_name}] ||= super end - CODE super end From 9a5b0251f238f431ff9c9b70a31f1aaf6a41b3de Mon Sep 17 00:00:00 2001 From: x4d3 Date: Thu, 30 Nov 2017 17:21:07 +0000 Subject: [PATCH 10/10] Fix and spec OmniauthCallbacksController.setup_apps --- .../jpi/v1/deletion_requests_controller.rb | 1 - .../auth/omniauth_callback_controller_spec.rb | 56 ++++++++- .../auth/omniauth_callbacks_controller.rb | 107 +++++++++--------- .../factories/orga_relations.rb | 3 + 4 files changed, 112 insertions(+), 55 deletions(-) diff --git a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/deletion_requests_controller.rb b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/deletion_requests_controller.rb index 4c55cc98b..40ef4e2a2 100644 --- a/api/lib/mno_enterprise/concerns/controllers/jpi/v1/deletion_requests_controller.rb +++ b/api/lib/mno_enterprise/concerns/controllers/jpi/v1/deletion_requests_controller.rb @@ -58,5 +58,4 @@ def destroy head :bad_request end end - end diff --git a/api/spec/controllers/mno_enterprise/auth/omniauth_callback_controller_spec.rb b/api/spec/controllers/mno_enterprise/auth/omniauth_callback_controller_spec.rb index 33f2d2e8f..ad64bff83 100644 --- a/api/spec/controllers/mno_enterprise/auth/omniauth_callback_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/auth/omniauth_callback_controller_spec.rb @@ -3,7 +3,9 @@ module MnoEnterprise describe Auth::OmniauthCallbacksController, type: :controller do routes { MnoEnterprise::Engine.routes } - supported_providers = %i(linkedin google facebook) + + ACTIVE_STATUSES = MnoEnterprise::AppInstance::ACTIVE_STATUSES.join(',') + describe 'provides callbacks for the providers' do before do @@ -17,5 +19,57 @@ module MnoEnterprise it { expect(controller).to respond_to(:intuit) } it { expect(controller).to respond_to(:facebook) } end + + describe '.setup_apps' do + let(:app) { build(:app) } + let(:app_instance) { build(:app_instance, app: app, oauth_keys_valid: false) } + let(:user) { build(:user) } + let(:orga_relation) { build(:orga_relation, :super_admin) } + let(:organization) { build(:organization) } + let(:app_nids) { [app.nid] } + let(:options) { {} } + let(:get_app_instances_params) { { filter: { 'owner.id': organization.id, 'status.in': ACTIVE_STATUSES } } } + + # setup_apps is a private method + subject { controller.send(:setup_apps, user, app_nids, options) } + + before do + stub_api_v2(:get, '/organizations', [organization], [], { filter: { 'users.id': user.id }, fields: { organizations: 'id' } }) + stub_api_v2(:get, '/orga_relations', [orga_relation], [], { filter: { 'user.id': user.id }, fields: { orga_relations: 'role' } }) + stub_api_v2(:get, '/apps', [app], [], { filter: { 'nid.in': app.nid }, fields: { apps: 'id,nid' } }) + end + + context 'when the app_instance already exists' do + before { stub_api_v2(:get, '/app_instances', [app_instance], [:app], get_app_instances_params) } + it 'does not create a new app instance' do + expect(subject.length).to be(1) + expect(subject.first.id).to eq(app_instance.id) + end + + describe 'when there is a oauth_keyset' do + let(:options) { { oauth_keyset: 'oauth_keyset' } } + let!(:stub) { stub_api_v2(:patch, "/app_instances/#{app_instance.id}", app_instance) } + it do + subject + expect(stub).to have_been_requested + end + end + + end + context 'when there is no previous app instance' do + let(:provisioned_app_instance) { build(:app_instance) } + before do + stub_audit_events + stub_api_v2(:get, '/app_instances', [], [:app], get_app_instances_params) + stub_api_v2(:get, '/app_instances/' + provisioned_app_instance.id, provisioned_app_instance, [:owner]) + end + let!(:stub) { stub_api_v2(:post, '/app_instances/provision', provisioned_app_instance) } + it 'provisions the app_instance' do + expect(subject.length).to be(1) + expect(subject.first.id).to eq(provisioned_app_instance.id) + expect(stub).to have_been_requested + end + end + end end end diff --git a/core/lib/mno_enterprise/concerns/controllers/auth/omniauth_callbacks_controller.rb b/core/lib/mno_enterprise/concerns/controllers/auth/omniauth_callbacks_controller.rb index 75de66a68..62fba11ac 100644 --- a/core/lib/mno_enterprise/concerns/controllers/auth/omniauth_callbacks_controller.rb +++ b/core/lib/mno_enterprise/concerns/controllers/auth/omniauth_callbacks_controller.rb @@ -99,7 +99,7 @@ def intuit # to the user orga # Only for new users for which an orga was created (not an invited user # typically) - app_instances = setup_apps(@user,['quickbooks',params[:app]], oauth_keyset: params[:app]) + app_instances = setup_apps(@user, ['quickbooks', params[:app]], oauth_keyset: params[:app]) qb_instance = app_instances.first # On Intuit, Mno is configured to add qb_initiated=true if the user @@ -141,63 +141,64 @@ def intuit #================================================ private - def cleanup_intuit_session - session.delete("omniauth.intuit.passthru_email") - session.delete("omniauth.intuit.request_account_link") - end + def cleanup_intuit_session + session.delete("omniauth.intuit.passthru_email") + session.delete("omniauth.intuit.request_account_link") + end - # Whether to create an orga on user creation - def create_orga_on_user_creation(user_email = nil) - return false if user_email.blank? - return false if MnoEnterprise::User.exists?(email: user_email) + # Whether to create an orga on user creation + def create_orga_on_user_creation(user_email = nil) + return false if user_email.blank? + return false if MnoEnterprise::User.exists?(email: user_email) - # First check previous url to see if the user - # was trying to accept an orga - if !session[:previous_url].blank? && (r = session[:previous_url].match(/\/orga_invites\/(\d+)\?token=(\w+)/)) - invite_params = { id: r.captures[0].to_i, token: r.captures[1] } - return false if MnoEnterprise::OrgaInvite.where(invite_params).any? - end - - # Get remaining invites via email address - return MnoEnterprise::OrgaInvite.where(user_email: user_email).empty? + # First check previous url to see if the user + # was trying to accept an orga + if !session[:previous_url].blank? && (r = session[:previous_url].match(/\/orga_invites\/(\d+)\?token=(\w+)/)) + invite_params = { id: r.captures[0].to_i, token: r.captures[1] } + return false if MnoEnterprise::OrgaInvite.where(invite_params).any? end - # Create or find the apps provided in argument - # Accept an array of app nid (named id - e.g: 'quickbooks') - # opts: - # oauth_keyset: If a oauth_keyset is provided then it will be added to the - # oauth_keys of any app that is oauth ready (QuickBooks for example) - # - # Return an array of app instances (found or created) - def setup_apps(user = nil, app_nids = [], opts = {}) - return [] unless user - return [] unless (user.organizations.reload.count == 1) - return [] unless (org = user.organizations.first) - return [] unless MnoEnterprise::Ability.new(user).can?(:edit,org) - - results = [] - - apps = MnoEnterprise::App.where(nid: app_nids.compact) - existing = org.app_instances.active.index_by(&:app_id) - - # For each app nid (which is not nil), try to find an existing instance or create one - apps.each do |app| - if (app_instance = existing[app.id]) - results << app_instance - else - # Provision instance and add to results - app_instance = org.provision_app_instance!(app.nid) - results << app_instance - MnoEnterprise::EventLogger.info('app_add', user.id, 'App added', app_instance) - end + # Get remaining invites via email address + return MnoEnterprise::OrgaInvite.where(user_email: user_email).empty? + end - # Add oauth keyset if defined and app_instance is - # oauth ready and does not have a valid set of oauth keys - if app_instance && opts[:oauth_keyset].present? && !app_instance.oauth_keys_valid - app_instance.oauth_keys = { keyset: opts[:oauth_keyset] } - app_instance.save - end + # Create or find the apps provided in argument + # Accept an array of app nid (named id - e.g: 'quickbooks') + # opts: + # oauth_keyset: If a oauth_keyset is provided then it will be added to the + # oauth_keys of any app that is oauth ready (QuickBooks for example) + # + # Return an array of app instances (found or created) + def setup_apps(user, app_nids, opts) + organizations = MnoEnterprise::Organization.where('users.id': user.id).select(:id) + orga_relations = MnoEnterprise::OrgaRelation.where('user.id': user.id).select(:role) + return [] unless (organizations.count == 1 && orga_relations.count == 1) + organization = organizations.first + return [] unless MnoEnterprise::Ability.new(user).can?(:update, orga_relations.first) + apps = MnoEnterprise::App.where('nid.in': app_nids.compact.join(',')).select('id,nid') + existing = MnoEnterprise::AppInstance + .where( + 'owner.id': organization.id, + 'status.in': MnoEnterprise::AppInstance::ACTIVE_STATUSES.join(',') + ).includes(:app) + .index_by { |a| a.app.id } + + # For each app nid (which is not nil), try to find an existing instance or create one + results = apps.map do |app| + unless (app_instance = existing[app.id]) + # Provision instance + app_instance = MnoEnterprise::AppInstance.provision!(app.nid, organization.id, 'Organization' ) + app_instance = app_instance.load_required(:owner) + MnoEnterprise::EventLogger.info('app_add', user.id, 'App added', app_instance) end - return results + # Add oauth keyset if defined and app_instance is + # oauth ready and does not have a valid set of oauth keys + if opts[:oauth_keyset].present? && !app_instance.oauth_keys_valid + app_instance.oauth_keys = { keyset: opts[:oauth_keyset] } + app_instance.save! + end + app_instance end + return results + end end diff --git a/core/lib/mno_enterprise/testing_support/factories/orga_relations.rb b/core/lib/mno_enterprise/testing_support/factories/orga_relations.rb index 4f921923c..d6d67d2d2 100644 --- a/core/lib/mno_enterprise/testing_support/factories/orga_relations.rb +++ b/core/lib/mno_enterprise/testing_support/factories/orga_relations.rb @@ -10,5 +10,8 @@ user_id '265' organization_id '265' role 'Admin' + trait :super_admin do + role 'Super Admin' + end end end