diff --git a/api/app/controllers/mno_enterprise/impersonate_controller.rb b/api/app/controllers/mno_enterprise/impersonate_controller.rb index 374838a71..80c2049ff 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) + @user = MnoEnterprise::User.find_one(params[:user_id], :deletion_requests, :organizations, :orga_relations, :dashboards, :teams, :user_access_requests, :sub_tenant) unless @user.present? return redirect_with_error('User does not exist') end 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 18b3b619b..1950a23dd 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 @@ -7,16 +7,23 @@ class Jpi::V1::Admin::OrganizationsController < Jpi::V1::Admin::BaseResourceCont :geo_country_code, :geo_state_code, :geo_city, :geo_tz, :geo_currency, :metadata, :industry, :size, :financial_year_end_month, :credit_card, - :financial_metrics, :created_at, :external_id] + :financial_metrics, :created_at, :external_id, :belong_to_sub_tenant, :belong_to_account_manager] + # GET /mnoe/jpi/v1/admin/organizations def index if params[:terms] # Search mode @organizations = [] JSON.parse(params[:terms]).map do |t| - @organizations = @organizations | MnoEnterprise::Organization.with_params(_metadata: { act_as_manager: current_user.id }) - .select(INCLUDED_FIELDS) - .where(Hash[*t]) + + query = MnoEnterprise::Organization + .apply_query_params(params.except(:terms)) + .select(INCLUDED_FIELDS) + .with_params(_metadata: { act_as_manager: current_user.id }) + .where(Hash[*t]) + query = query.with_params(sub_tenant_id: params[:sub_tenant_id]) if params[:sub_tenant_id] + query = query.with_params(account_manager_id: params[:account_manager_id]) if params[:account_manager_id] + @organizations = @organizations | query end response.headers['X-Total-Count'] = @organizations.count else @@ -26,7 +33,8 @@ def index .apply_query_params(params) .with_params(_metadata: { act_as_manager: current_user.id }) .select(INCLUDED_FIELDS) - + query = query.with_params(sub_tenant_id: params[:sub_tenant_id]) if params[:sub_tenant_id] + query = query.with_params(account_manager_id: params[:account_manager_id]) if params[:account_manager_id] @organizations = query.to_a response.headers['X-Total-Count'] = query.meta.record_count end @@ -82,9 +90,9 @@ def update return render_not_found('Organization') unless @organization # Update organization + update_app_list @organization.update!(organization_update_params) - update_app_list @organization = @organization.load_required(*DEPENDENCIES) @organization_active_apps = @organization.app_instances.select(&:active?) diff --git a/api/app/controllers/mno_enterprise/jpi/v1/admin/sub_tenants_controller.rb b/api/app/controllers/mno_enterprise/jpi/v1/admin/sub_tenants_controller.rb index 89ff2d921..870e166de 100644 --- a/api/app/controllers/mno_enterprise/jpi/v1/admin/sub_tenants_controller.rb +++ b/api/app/controllers/mno_enterprise/jpi/v1/admin/sub_tenants_controller.rb @@ -13,9 +13,7 @@ def index # GET /mnoe/jpi/v1/admin/sub_tenants/1 def show - @sub_tenant = MnoEnterprise::SubTenant.find_one(params[:id], :clients, :account_managers) - @sub_tenant_clients = @sub_tenant.clients - @sub_tenant_account_managers = @sub_tenant.account_managers + @sub_tenant = MnoEnterprise::SubTenant.find_one(params[:id]) end # POST /mnoe/jpi/v1/admin/sub_tenants @@ -28,9 +26,22 @@ def create def update @sub_tenant = MnoEnterprise::SubTenant.find_one(params[:id]) @sub_tenant.update!(sub_tenant_params) - @sub_tenant = @sub_tenant.load_required(:clients, :account_managers) - @sub_tenant_clients = @sub_tenant.clients - @sub_tenant_account_managers = @sub_tenant.account_managers + render :show + end + + # PATCH /mnoe/jpi/v1/admin/organizations/1/update_clients + def update_clients + @sub_tenant = MnoEnterprise::SubTenant.find_one(params[:id]) + attributes = params.require(:sub_tenant).permit(add: [], remove: []) + @sub_tenant.update_clients!({data: {attributes: attributes}}) + render :show + end + + # PATCH /mnoe/jpi/v1/admin/organizations/1/update_account_managers + def update_account_managers + @sub_tenant = MnoEnterprise::SubTenant.find_one(params[:id]) + attributes = params.require(:sub_tenant).permit(add: [], remove: []) + @sub_tenant.update_account_managers!({data: {attributes: attributes}}) render :show end @@ -47,11 +58,7 @@ def check_sub_tenant_authorization private def sub_tenant_params - sub_tenant_params = params.require(:sub_tenant) - allowed_params = sub_tenant_params.permit(:name, client_ids: [], account_manager_ids: []) - allowed_params[:client_ids] ||= [] if sub_tenant_params.has_key?(:client_ids) - allowed_params[:account_manager_ids] ||= [] if sub_tenant_params.has_key?(:account_manager_ids) - allowed_params + params.require(:sub_tenant).permit(:name) end end end 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 2f2782073..f88194735 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 @@ -7,9 +7,11 @@ def index # Search mode @users = [] JSON.parse(params[:terms]).map do |t| - @users = @users | MnoEnterprise::User.with_params(_metadata: { act_as_manager: current_user.id }) - .includes(:user_access_requests) - .where(Hash[*t]) + @users = @users | MnoEnterprise::User + .apply_query_params(params.except(:terms)) + .with_params(_metadata: { act_as_manager: current_user.id }) + .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 @@ -22,7 +24,7 @@ def index query = MnoEnterprise::User .apply_query_params(params) .with_params(_metadata: { act_as_manager: current_user.id }) - .includes(:user_access_requests) + .includes(:user_access_requests, :sub_tenant) @users = query.to_a response.headers['X-Total-Count'] = query.meta.record_count end @@ -31,18 +33,19 @@ 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, :clients) + .includes(:orga_relations, :organizations, :user_access_requests, :sub_tenant) .find(params[:id]) .first @user_organizations = @user.organizations - @user_clients = @user.clients end # POST /mnoe/jpi/v1/admin/users def create - @user = MnoEnterprise::User.create!(user_create_params) - @user = @user.load_required(:clients) + @user = MnoEnterprise::User.new(user_create_params) + update_sub_tenant(@user) + @user.save! + @user = @user.load_required(:sub_tenant) render :show end @@ -58,12 +61,20 @@ def update # (the current_user may not have access to this record) @user = MnoEnterprise::User.with_params(_metadata: { act_as_manager: current_user.id }).find(params[:id]).first return render_not_found('User') unless @user + @user.attributes = user_update_params + update_sub_tenant(@user) + @user.save! + @user = @user.load_required(:sub_tenant) + render :show + end - # Update user - @user.update!(user_update_params) - - @user = @user.load_required(:clients) - @user_clients = @user.clients + # PATCH /mnoe/jpi/v1/admin/organizations/1/update_clients + 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 = @user.load_required(:sub_tenant) render :show end @@ -107,25 +118,26 @@ def tenant_reporting end def user_update_params - attrs = [:name, :surname, :email, :phone, client_ids: []] + attrs = [:name, :surname, :email, :phone] # TODO: replace with authorize/ability if current_user.admin_role == 'admin' attrs << :admin_role - attrs << :mnoe_sub_tenant_id end - user_param = params.require(:user) - updated_params = user_param.permit(attrs) - updated_params[:sub_tenant_id] = updated_params.delete(:mnoe_sub_tenant_id) - updated_params[:client_ids] ||= [] if user_param.has_key?(:client_ids) - # if the user is updated to admin or division admin, his clients are cleared - if updated_params[:admin_role] && updated_params[:admin_role] != 'staff' - updated_params[:client_ids] = [] - end - updated_params + params.require(:user).permit(attrs) end def user_create_params user_update_params.merge(password: Devise.friendly_token.first(12)) end + + def update_sub_tenant(user) + if current_user.admin_role == 'admin' && params.require(:user).has_key?(:sub_tenant_id) + if params.require(:user)[:sub_tenant_id] + user.relationships.sub_tenant = MnoEnterprise::SubTenant.new(id: params.require(:user)[:sub_tenant_id]) + else + user.relationships.sub_tenant = nil + end + end + end end end diff --git a/api/app/views/mno_enterprise/jpi/v1/admin/organizations/_organization.json.jbuilder b/api/app/views/mno_enterprise/jpi/v1/admin/organizations/_organization.json.jbuilder index 656210906..2c29fcaf6 100644 --- a/api/app/views/mno_enterprise/jpi/v1/admin/organizations/_organization.json.jbuilder +++ b/api/app/views/mno_enterprise/jpi/v1/admin/organizations/_organization.json.jbuilder @@ -1 +1,2 @@ -json.extract! organization, :id, :name, :uid, :soa_enabled, :created_at, :account_frozen, :financial_metrics, :billing_currency, :external_id +json.extract! organization, :id, :name, :uid, :soa_enabled, :created_at, :account_frozen, :financial_metrics, :billing_currency, :external_id, :belong_to_sub_tenant, :belong_to_account_manager + diff --git a/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/_sub_tenant.json.jbuilder b/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/_sub_tenant.json.jbuilder index d07cb9220..a5cc72e16 100644 --- a/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/_sub_tenant.json.jbuilder +++ b/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/_sub_tenant.json.jbuilder @@ -1 +1 @@ -json.extract! sub_tenant, :id, :name, :created_at, :updated_at, :client_ids, :account_manager_ids +json.extract! sub_tenant, :id, :name, :created_at, :updated_at diff --git a/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/index.json.jbuilder b/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/index.json.jbuilder index e4c1b7f07..bd384e5e4 100644 --- a/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/index.json.jbuilder +++ b/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/index.json.jbuilder @@ -1,2 +1 @@ json.sub_tenants @sub_tenants, partial: 'sub_tenant', as: :sub_tenant -json.metadata @sub_tenants.metadata if @sub_tenants.respond_to?(:metadata) diff --git a/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/show.json.jbuilder b/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/show.json.jbuilder index 35104ae8a..ad36e098d 100644 --- a/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/show.json.jbuilder +++ b/api/app/views/mno_enterprise/jpi/v1/admin/sub_tenants/show.json.jbuilder @@ -1,12 +1,3 @@ json.sub_tenant do json.partial! 'sub_tenant', sub_tenant: @sub_tenant - - json.clients @sub_tenant_clients do |org| - json.extract! org, :id, :uid, :name, :created_at - end - - json.account_managers @sub_tenant_account_managers do |user| - json.extract! user, :id, :uid, :name, :surname, :email, :created_at, :admin_role - end - end diff --git a/api/app/views/mno_enterprise/jpi/v1/admin/users/_user.json.jbuilder b/api/app/views/mno_enterprise/jpi/v1/admin/users/_user.json.jbuilder index ba18fb477..ad6307472 100644 --- a/api/app/views/mno_enterprise/jpi/v1/admin/users/_user.json.jbuilder +++ b/api/app/views/mno_enterprise/jpi/v1/admin/users/_user.json.jbuilder @@ -1,3 +1,3 @@ -json.extract! user, :id, :uid, :email, :phone, :name, :surname, :admin_role, :created_at, :updated_at, :confirmed_at, :last_sign_in_at, :sign_in_count, :client_ids -json.mnoe_sub_tenant_id user.sub_tenant_id +json.extract! user, :id, :uid, :email, :phone, :name, :surname, :admin_role, :created_at, :updated_at, :confirmed_at, :last_sign_in_at, :sign_in_count +json.sub_tenant_id user.sub_tenant&.id json.access_request_status user.access_request_status(current_user) diff --git a/api/app/views/mno_enterprise/jpi/v1/admin/users/show.json.jbuilder b/api/app/views/mno_enterprise/jpi/v1/admin/users/show.json.jbuilder index 318872282..d4f830635 100644 --- a/api/app/views/mno_enterprise/jpi/v1/admin/users/show.json.jbuilder +++ b/api/app/views/mno_enterprise/jpi/v1/admin/users/show.json.jbuilder @@ -4,8 +4,4 @@ json.user do json.organizations @user_organizations do |org| json.extract! org, :id, :uid, :name, :account_frozen, :created_at end - - json.clients @user_clients do |org| - json.extract! org, :id, :uid, :name, :account_frozen, :created_at - end end diff --git a/api/app/views/mno_enterprise/jpi/v1/current_users/show.json.jbuilder b/api/app/views/mno_enterprise/jpi/v1/current_users/show.json.jbuilder index 7f6ce8644..a09f6943f 100644 --- a/api/app/views/mno_enterprise/jpi/v1/current_users/show.json.jbuilder +++ b/api/app/views/mno_enterprise/jpi/v1/current_users/show.json.jbuilder @@ -17,7 +17,7 @@ json.cache! ['v2', @user.cache_key] do json.admin_role @user.admin_role json.avatar_url avatar_url(@user) json.settings @user.settings - json.mnoe_sub_tenant_id @user.sub_tenant_id + json.sub_tenant_id @user.sub_tenant&.id if current_impersonator json.current_impersonator true diff --git a/api/config/routes.rb b/api/config/routes.rb index 832dcd30d..e3dacc96c 100644 --- a/api/config/routes.rb +++ b/api/config/routes.rb @@ -220,6 +220,9 @@ post :signup_email end resource :user_access_requests, only: [:create] + member do + patch :update_clients + end end resources :products, only: [:index, :show] @@ -266,7 +269,12 @@ end end - resources :sub_tenants, only: [:index, :show, :destroy, :update, :create] + resources :sub_tenants, only: [:index, :show, :destroy, :update, :create] do + member do + patch :update_clients + patch :update_account_managers + end + end resources :tenant_invoices, only: [:index, :show] diff --git a/api/spec/controllers/mno_enterprise/impersonate_controller_spec.rb b/api/spec/controllers/mno_enterprise/impersonate_controller_spec.rb index 6ef6cb59b..c430eb993 100644 --- a/api/spec/controllers/mno_enterprise/impersonate_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/impersonate_controller_spec.rb @@ -9,7 +9,7 @@ module MnoEnterprise 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)) + stub_api_v2(:get, "/users/#{user2.id}", user2, %i(deletion_requests organizations orga_relations dashboards teams user_access_requests sub_tenant)) stub_api_v2(:patch, "/users/#{user.id}") stub_api_v2(:patch, "/users/#{user2.id}") @@ -37,7 +37,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)) } + before { stub_api_v2(:get, '/users/crappyId', [], %i(deletion_requests organizations orga_relations dashboards teams user_access_requests sub_tenant)) } 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/organizations_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/organizations_controller_spec.rb index 2870426db..6c62e4a84 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 @@ -32,7 +32,8 @@ module MnoEnterprise { organizations: [ :uid, :name, :account_frozen, :soa_enabled, :mails, :logo, :latitude, :longitude, :geo_country_code, :geo_state_code, - :geo_city, :geo_tz, :geo_currency, :metadata, :industry, :size, :financial_year_end_month, :credit_card, :financial_metrics, :created_at, :external_id + :geo_city, :geo_tz, :geo_currency, :metadata, :industry, :size, :financial_year_end_month, :credit_card, :financial_metrics, :created_at, :external_id, + :belong_to_sub_tenant, :belong_to_account_manager ].join(',') } end diff --git a/api/spec/controllers/mno_enterprise/jpi/v1/admin/sub_tenants_controller_spec.rb b/api/spec/controllers/mno_enterprise/jpi/v1/admin/sub_tenants_controller_spec.rb index 6b7c1107d..33d693589 100644 --- a/api/spec/controllers/mno_enterprise/jpi/v1/admin/sub_tenants_controller_spec.rb +++ b/api/spec/controllers/mno_enterprise/jpi/v1/admin/sub_tenants_controller_spec.rb @@ -14,12 +14,7 @@ def hash_for_sub_tenants(sub_tenants) end def hash_for_sub_tenant(s) - hash = partial_hash_for_sub_tenant(s).merge( - { - 'clients' => s.clients.map { |c| hash_for_client(c) }, - 'account_managers' => s.account_managers.map { |c| hash_account_manager(c) }, - }) - { 'sub_tenant' => hash } + { 'sub_tenant' => partial_hash_for_sub_tenant(s) } end def partial_hash_for_sub_tenant(s) @@ -27,30 +22,7 @@ def partial_hash_for_sub_tenant(s) 'id' => s.id, 'name' => s.name, 'created_at' => s.created_at, - 'updated_at' => s.updated_at, - 'client_ids' => s.client_ids, - 'account_manager_ids' => s.account_manager_ids - } - end - - def hash_for_client(client) - { - 'id' => client.id, - 'uid' => client.uid, - 'name' => client.name, - 'created_at' => client.created_at - } - end - - def hash_account_manager(user) - { - 'id' => user.id, - 'uid' => user.uid, - 'name' => user.name, - 'surname' => user.surname, - 'email' => user.email, - 'created_at' => user.created_at, - 'admin_role' => user.admin_role + 'updated_at' => s.updated_at } end @@ -66,9 +38,7 @@ def hash_account_manager(user) # Specs #=============================================== let!(:user) { build(:user, :admin) } - let(:account_manager) { build(:user) } - let(:client) { build(:organization) } - let(:sub_tenant) { build(:sub_tenant, account_managers: [account_manager], clients: [client]) } + let(:sub_tenant) { build(:sub_tenant) } let!(:current_user_stub) { stub_user(user) } describe '#index' do @@ -96,7 +66,7 @@ def hash_account_manager(user) subject { get :show, id: sub_tenant.id } before do - stub_api_v2(:get, "/sub_tenants/#{sub_tenant.id}", sub_tenant, %i(clients account_managers)) + stub_api_v2(:get, "/sub_tenants/#{sub_tenant.id}", sub_tenant) end context 'not admin' do let!(:user) { build(:user) } @@ -121,7 +91,6 @@ def hash_account_manager(user) subject { put :update, id: sub_tenant.id, sub_tenant: { name: 'new name' } } before do stub_api_v2(:get, "/sub_tenants/#{sub_tenant.id}", sub_tenant) - stub_api_v2(:get, "/sub_tenants/#{sub_tenant.id}", sub_tenant, %i(clients account_managers)) sign_in user end let!(:stub) { stub_api_v2(:patch, "/sub_tenants/#{sub_tenant.id}", sub_tenant) } @@ -138,6 +107,49 @@ def hash_account_manager(user) end end end + + describe 'PATCH #update_clients' do + subject { put :update_clients, id: sub_tenant.id, sub_tenant: { add: [] } } + before do + stub_api_v2(:get, "/sub_tenants/#{sub_tenant.id}", sub_tenant) + sign_in user + end + let!(:stub) { stub_api_v2(:patch, "/sub_tenants/#{sub_tenant.id}/update_clients", sub_tenant) } + context 'not admin' do + let!(:user) { build(:user) } + it_behaves_like 'unauthorized access' + end + it_behaves_like 'a jpi v1 admin action' + context 'admin' do + context 'success' do + before { subject } + it { expect(response).to be_success } + it { expect(stub).to have_been_requested } + end + end + end + + describe 'PATCH #update_account_managers' do + subject { put :update_account_managers, id: sub_tenant.id, sub_tenant: { add: [] } } + before do + stub_api_v2(:get, "/sub_tenants/#{sub_tenant.id}", sub_tenant) + sign_in user + end + let!(:stub) { stub_api_v2(:patch, "/sub_tenants/#{sub_tenant.id}/update_account_managers", sub_tenant) } + context 'not admin' do + let!(:user) { build(:user) } + it_behaves_like 'unauthorized access' + end + it_behaves_like 'a jpi v1 admin action' + context 'admin' do + context 'success' do + before { subject } + it { expect(response).to be_success } + it { expect(stub).to have_been_requested } + end + end + end + describe 'DELETE #destroy' do subject { delete :destroy, id: sub_tenant.id } before do 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 993158003..c0242c25a 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 @@ -27,7 +27,7 @@ module MnoEnterprise let(:data) { JSON.parse(response.body) } - before { stub_api_v2(:get, "/users", [user], [:user_access_requests], { _metadata: { act_as_manager: current_user.id } }) } + before { stub_api_v2(:get, "/users", [user], [:user_access_requests, :sub_tenant], { _metadata: { act_as_manager: current_user.id } }) } before { subject } it { expect(data['users'].first['id']).to eq(user.id) } @@ -37,9 +37,8 @@ module MnoEnterprise subject { get :show, id: user.id } let(:data) { JSON.parse(response.body) } - let(:included) { [:orga_relations, :organizations, :user_access_requests, :clients] } + let(:included) { [:orga_relations, :organizations, :user_access_requests, :sub_tenant] } - before { allow(user).to receive(:clients).and_return([]) } before { stub_api_v2(:get, "/users/#{user.id}", user, included, { _metadata: { act_as_manager: current_user.id } }) } before { subject } @@ -47,18 +46,27 @@ module MnoEnterprise end describe 'POST #create' do + let(:confirmation_token) { '1e243fa1180e32f3ec66a648835d1fbca7912223a487eac36be22b095a01b5a5' } + before { + Devise.token_generator + stub_api_v2(:get, '/users', [], [], { filter: { email: 'test@toto.com' }, page: { number: 1, size: 1 } }) + stub_api_v2(:get, '/users', [], [], { filter: { confirmation_token: confirmation_token } }) + stub_api_v2(:get, "/users/#{user.id}", user, [:sub_tenant]) + stub_api_v2(:patch, "/users/#{user.id}", user) + allow_any_instance_of(Devise::TokenGenerator).to receive(:digest).and_return(confirmation_token) + allow_any_instance_of(Devise::TokenGenerator).to receive(:generate).and_return(confirmation_token) + } subject { post :create, user: params } let(:data) { JSON.parse(response.body) } - let(:params) { { 'name' => 'Foo' } } + let(:params) { { 'name' => 'Foo', 'email' => 'test@toto.com' } } let(:expected_params) { params.merge('sub_tenant_id' => nil) } + let!(:stub) { stub_api_v2(:post, '/users', user) } - before { allow(user).to receive(:clients).and_return([]) } - before { expect(MnoEnterprise::User).to receive(:create).with(hash_including(expected_params)).and_return(user) } - before { stub_api_v2(:get, "/users/#{user.id}", user, [:clients]) } before { subject } it { expect(data['user']['id']).to eq(user.id) } + it { expect(stub).to have_been_requested } end describe 'PUT #update' do @@ -68,21 +76,33 @@ module MnoEnterprise let(:params) { { 'name' => 'Foo' } } let(:expected_params) { params.merge('sub_tenant_id' => nil) } - before { allow(user).to receive(:clients).and_return([]) } - before { expect_any_instance_of(MnoEnterprise::User).to receive(:update).with(expected_params) } + before { expect_any_instance_of(MnoEnterprise::User).to receive(:save) } before { stub_api_v2(:get, "/users/#{user.id}", user, [], { _metadata: { act_as_manager: current_user.id } }) } - before { stub_api_v2(:get, "/users/#{user.id}", user, [:clients]) } + before { stub_api_v2(:get, "/users/#{user.id}", user, [:sub_tenant]) } before { subject } it { expect(data['user']['id']).to eq(user.id) } end + describe 'PATCH #update_clients' do + subject { put :update_clients, id: user.id, user: params } + + let(:data) { JSON.parse(response.body) } + let(:params) { { add: ['id'] } } + + before { stub_api_v2(:get, "/users/#{user.id}", user, [], { _metadata: { act_as_manager: current_user.id } }) } + before { stub_api_v2(:get, "/users/#{user.id}", user, [:sub_tenant]) } + let!(:stub) { stub_api_v2(:patch, "/users/#{user.id}/update_clients", user) } + before { subject } + it { expect(data['user']['id']).to eq(user.id) } + it { expect(stub).to have_been_requested } + end + describe 'DELETE #destroy' do subject { delete :destroy, id: user.id } let(:data) { JSON.parse(response.body) } - before { allow(user).to receive(:clients).and_return([]) } before { expect_any_instance_of(MnoEnterprise::User).to receive(:destroy) } before { stub_api_v2(:get, "/users/#{user.id}", user, [], { _metadata: { act_as_manager: current_user.id } }) } 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 58aeb3bb7..39ad42796 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 @@ -35,7 +35,7 @@ def hash_for(res) 'admin_role' => res.admin_role, 'avatar_url' => avatar_url(res), 'settings' => res.settings, - 'mnoe_sub_tenant_id' => res.sub_tenant_id, + 'sub_tenant_id' => res.sub_tenant&.id, 'user_hash' => res.intercom_user_hash } @@ -108,7 +108,7 @@ def hash_for(res) it 'returns the right response' do subject - expect(response.body).to eq(json_for(user)) + expect(JSON.parse(response.body)).to eq(json_hash_for(user)) end end end diff --git a/core/app/helpers/mno_enterprise/impersonate_helper.rb b/core/app/helpers/mno_enterprise/impersonate_helper.rb index ed2ba5ee2..651ec6462 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) + @admin_user ||= MnoEnterprise::User.find_one(session[:impersonator_user_id], :deletion_requests, :organizations, :orga_relations, :dashboards, :teams, :sub_tenant) end end diff --git a/core/app/models/mno_enterprise/sub_tenant.rb b/core/app/models/mno_enterprise/sub_tenant.rb index 236a68353..b7c620081 100644 --- a/core/app/models/mno_enterprise/sub_tenant.rb +++ b/core/app/models/mno_enterprise/sub_tenant.rb @@ -3,7 +3,18 @@ class SubTenant < BaseResource property :created_at, type: :time property :updated_at, type: :time property :name - property :account_manager_ids - property :client_ids + + custom_endpoint :update_clients, on: :member, request_method: :patch + custom_endpoint :update_account_managers, on: :member, request_method: :patch + + def update_clients!(input) + result = self.update_clients(input) + process_custom_result(result) + end + + def update_account_managers!(input) + result = self.update_account_managers(input) + process_custom_result(result) + end end end diff --git a/core/app/models/mno_enterprise/user.rb b/core/app/models/mno_enterprise/user.rb index 486ff2b4d..b9086dc2c 100644 --- a/core/app/models/mno_enterprise/user.rb +++ b/core/app/models/mno_enterprise/user.rb @@ -7,7 +7,7 @@ class User < BaseResource include ActiveModel::AttributeMethods include ActiveModel::Validations - INCLUDED_DEPENDENCIES = %i(deletion_requests organizations orga_relations dashboards teams) + INCLUDED_DEPENDENCIES = %i(deletion_requests organizations orga_relations dashboards teams sub_tenant) # ids property :id @@ -41,8 +41,7 @@ class User < BaseResource property :surname, type: :string property :website, type: :string - property :sub_tenant_id, type: :string - property :client_ids + has_one :sub_tenant define_model_callbacks :validation #required by Devise define_model_callbacks :update #required by Devise @@ -77,6 +76,7 @@ def initialize(params = {}) custom_endpoint :create_api_credentials, on: :member, request_method: :patch custom_endpoint :authenticate, on: :collection, request_method: :post custom_endpoint :update_password, on: :member, request_method: :patch + custom_endpoint :update_clients, on: :member, request_method: :patch #================================ # Class Methods @@ -150,6 +150,11 @@ def create_api_credentials! process_custom_result(result) end + def update_clients!(input) + result = update_clients(input) + process_custom_result(result) + end + # Find a user using a confirmation token def self.find_for_confirmation(confirmation_token) original_token = confirmation_token diff --git a/core/lib/mno_enterprise/concerns/models/organization.rb b/core/lib/mno_enterprise/concerns/models/organization.rb index 3c6ef1680..5f35d843d 100644 --- a/core/lib/mno_enterprise/concerns/models/organization.rb +++ b/core/lib/mno_enterprise/concerns/models/organization.rb @@ -35,6 +35,8 @@ module MnoEnterprise::Concerns::Models::Organization property :financial_metrics property :billing_currency property :external_id, type: :string + property :belong_to_sub_tenant, type: :boolean + property :belong_to_account_manager, type: :boolean 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 7f9eede8d..8fc3081bc 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 @@ -51,7 +51,7 @@ def stub_audit_events end def stub_user(user) - stub_api_v2(:get, "/users/#{user.id}", user, %i(deletion_requests organizations orga_relations dashboards teams)) + stub_api_v2(:get, "/users/#{user.id}", user, %i(deletion_requests organizations orga_relations dashboards teams sub_tenant)) end def api_v2_url(suffix, included = [], params = {})