diff --git a/app/controllers/v3/apps_controller.rb b/app/controllers/v3/apps_controller.rb index 1284747123c..6406d6f857b 100644 --- a/app/controllers/v3/apps_controller.rb +++ b/app/controllers/v3/apps_controller.rb @@ -32,6 +32,7 @@ require 'fetchers/app_fetcher' require 'fetchers/app_delete_fetcher' require 'fetchers/assign_current_droplet_fetcher' +require 'repositories/app_event_repository' class AppsV3Controller < ApplicationController def index @@ -245,6 +246,8 @@ def show_env FeatureFlag.raise_unless_enabled!(:space_developer_env_var_visibility) + Repositories::AppEventRepository.new.record_app_show_env(app, user_audit_info) + render status: :ok, json: Presenters::V3::AppEnvPresenter.new(app) end @@ -258,6 +261,8 @@ def show_environment_variables FeatureFlag.raise_unless_enabled!(:space_developer_env_var_visibility) + Repositories::AppEventRepository.new.record_app_show_environment_variables(app, user_audit_info) + render status: :ok, json: Presenters::V3::AppEnvironmentVariablesPresenter.new(app) end diff --git a/app/controllers/v3/revisions_controller.rb b/app/controllers/v3/revisions_controller.rb index 9e5677e26d4..3d13ced0c5b 100644 --- a/app/controllers/v3/revisions_controller.rb +++ b/app/controllers/v3/revisions_controller.rb @@ -2,6 +2,7 @@ require 'actions/revisions_update' require 'presenters/v3/revision_presenter' require 'presenters/v3/revision_environment_variables_presenter' +require 'repositories/revision_event_repository' class RevisionsController < ApplicationController def show @@ -22,6 +23,7 @@ def update def show_environment_variables revision = fetch_revision(hashed_params[:revision_guid], needs_secrets_read_permission: true) + Repositories::RevisionEventRepository.record_show_environment_variables(revision, revision.app, user_audit_info) render status: :ok, json: Presenters::V3::RevisionEnvironmentVariablesPresenter.new(revision) end diff --git a/app/repositories/app_event_repository.rb b/app/repositories/app_event_repository.rb index ab51dbbe49a..cd8752b9765 100644 --- a/app/repositories/app_event_repository.rb +++ b/app/repositories/app_event_repository.rb @@ -155,6 +155,16 @@ def record_app_ssh_authorized(app, user_audit_info, index) create_app_audit_event('audit.app.ssh-authorized', app, app.space, actor_hash, { index: index }) end + def record_app_show_env(app, user_audit_info) + actor_hash = { name: user_audit_info.user_email, guid: user_audit_info.user_guid, user_name: user_audit_info.user_name, type: 'user' } + create_app_audit_event('audit.app.environment.show', app, app.space, actor_hash, {}) + end + + def record_app_show_environment_variables(app, user_audit_info) + actor_hash = { name: user_audit_info.user_email, guid: user_audit_info.user_guid, user_name: user_audit_info.user_name, type: 'user' } + create_app_audit_event('audit.app.environment_variables.show', app, app.space, actor_hash, {}) + end + private def create_app_audit_event(type, app, space, actor, metadata) diff --git a/app/repositories/revision_event_repository.rb b/app/repositories/revision_event_repository.rb index 42a6a237830..5ec6fde58ad 100644 --- a/app/repositories/revision_event_repository.rb +++ b/app/repositories/revision_event_repository.rb @@ -22,6 +22,26 @@ def self.record_create(revision, app, user_audit_info) organization_guid: app.space.organization_guid, ) end + + def self.record_show_environment_variables(revision, app, user_audit_info) + Event.create( + type: 'audit.app.revision.environment_variables.show', + actor: user_audit_info.user_guid, + actor_type: 'user', + actor_name: user_audit_info.user_email, + actor_username: user_audit_info.user_name, + actee: app.guid, + actee_type: 'app', + actee_name: app.name, + timestamp: Sequel::CURRENT_TIMESTAMP, + metadata: { + revision_guid: revision.guid, + revision_version: revision.version + }, + space_guid: app.space_guid, + organization_guid: app.space.organization_guid, + ) + end end end end diff --git a/spec/unit/controllers/v3/apps_controller_spec.rb b/spec/unit/controllers/v3/apps_controller_spec.rb index ef8dd38e412..34abbd2fe58 100644 --- a/spec/unit/controllers/v3/apps_controller_spec.rb +++ b/spec/unit/controllers/v3/apps_controller_spec.rb @@ -1718,7 +1718,7 @@ let(:user) { VCAP::CloudController::User.make } before do - set_current_user(user) + set_current_user(user, email: 'mona@example.com') allow_user_read_access_for(user, spaces: [space]) allow_user_write_access(user, space: space) allow_user_secret_access(user, space: space) @@ -1732,6 +1732,25 @@ expect(parsed_body['environment_variables']).to eq(app_model.environment_variables) end + it 'records an audit event' do + expect { + get :show_env, params: { guid: app_model.guid } + }.to change { VCAP::CloudController::Event.count }.by(1) + + event = VCAP::CloudController::Event.find(type: 'audit.app.environment.show') + expect(event).not_to be_nil + expect(event.actor).to eq(user.guid) + expect(event.actor_type).to eq('user') + expect(event.actor_name).to eq('mona@example.com') + expect(event.actee).to eq(app_model.guid) + expect(event.actee_type).to eq('app') + expect(event.actee_name).to eq(app_model.name) + expect(event.timestamp).to be + expect(event.space_guid).to eq(app_model.space_guid) + expect(event.organization_guid).to eq(app_model.space.organization.guid) + expect(event.metadata).to eq({}) + end + context 'permissions' do context 'when the user does not have read permissions' do before do @@ -1977,6 +1996,27 @@ }) end end + + it 'records an audit event' do + set_current_user_as_admin(user: user, email: 'mona@example.com') + + expect { + get :show_environment_variables, params: { guid: app_model.guid }, as: :json + }.to change { VCAP::CloudController::Event.count }.by(1) + + event = VCAP::CloudController::Event.find(type: 'audit.app.environment_variables.show') + expect(event).not_to be_nil + expect(event.actor).to eq(user.guid) + expect(event.actor_type).to eq('user') + expect(event.actor_name).to eq('mona@example.com') + expect(event.actee).to eq(app_model.guid) + expect(event.actee_type).to eq('app') + expect(event.actee_name).to eq(app_model.name) + expect(event.timestamp).to be + expect(event.space_guid).to eq(app_model.space_guid) + expect(event.organization_guid).to eq(app_model.space.organization.guid) + expect(event.metadata).to eq({}) + end end describe '#update_environment_variables' do diff --git a/spec/unit/controllers/v3/revisions_controller_spec.rb b/spec/unit/controllers/v3/revisions_controller_spec.rb index 2a9439c0d33..23ece85a617 100644 --- a/spec/unit/controllers/v3/revisions_controller_spec.rb +++ b/spec/unit/controllers/v3/revisions_controller_spec.rb @@ -343,7 +343,7 @@ } before do - set_current_user(user) + set_current_user(user, email: 'mona@example.com') allow_user_read_access_for(user, spaces: [space]) allow_user_secret_access(user, space: space) end @@ -355,6 +355,28 @@ expect(parsed_body['var']).to eq({ 'key' => 'value' }) end + it 'records an audit event' do + expect { + get :show_environment_variables, params: { revision_guid: revision.guid } + }.to change { VCAP::CloudController::Event.count }.by(1) + + event = VCAP::CloudController::Event.find(type: 'audit.app.revision.environment_variables.show') + expect(event).not_to be_nil + expect(event.actor).to eq(user.guid) + expect(event.actor_type).to eq('user') + expect(event.actor_name).to eq('mona@example.com') + expect(event.actee).to eq(app_model.guid) + expect(event.actee_type).to eq('app') + expect(event.actee_name).to eq(app_model.name) + expect(event.timestamp).to be + expect(event.space_guid).to eq(app_model.space_guid) + expect(event.organization_guid).to eq(app_model.space.organization.guid) + expect(event.metadata).to eq({ + 'revision_guid' => revision.guid, + 'revision_version' => revision.version, + }) + end + context 'when retrieving env variables for revision that do not exist' do it '404s' do get :show_environment_variables, params: { revision_guid: 'nonsense' }