From 0dcc377a5933805c4e898ff676856cd85866f3b1 Mon Sep 17 00:00:00 2001 From: Kenneth Koski Date: Wed, 1 Mar 2017 19:11:28 -0600 Subject: [PATCH] Converting Rails config to railsconfig (#823) * Converting Rails config to railsconfig --- .gitignore | 4 + Gemfile | 1 + Gemfile.lock | 5 + Jenkinsfile | 38 +---- README.md | 155 ++++++++++++------ app/controllers/v0/sessions_controller.rb | 10 +- app/mailers/year_to_date_report_mailer.rb | 8 +- app/models/education_benefits_claim.rb | 2 +- app/models/in_progress_form.rb | 2 +- app/models/mvi.rb | 2 +- app/models/nca_facility_adapter.rb | 2 +- app/models/vba_facility_adapter.rb | 2 +- app/models/vha_facility_adapter.rb | 2 +- .../disability_claim_document_uploader.rb | 6 +- app/uploaders/evss_claim_document_uploader.rb | 6 +- app/workers/education_form/writer/factory.rb | 6 +- app/workers/education_form/writer/remote.rb | 2 +- config/application.rb | 4 +- config/application.yml.example | 35 ---- config/database.yml | 9 +- config/environments/development.rb | 2 +- config/environments/production.rb | 2 +- config/environments/test.rb | 2 +- config/health_care_application.yml | 26 --- config/initializers/config.rb | 37 +++++ config/initializers/figaro.rb | 38 ----- .../override_redirect_to_logging.rb | 5 +- config/initializers/saml.rb | 3 + .../mvi_schema/IdmWebService_200VGOV.wsdl.erb | 2 +- config/redis.yml | 4 +- config/saml.yml | 22 --- config/secrets.yml | 6 +- config/settings.yml | 101 ++++++++++++ config/settings/development.yml | 0 config/settings/production.yml | 0 config/settings/test.yml | 16 ++ docs/setup/authentication_with_idme.md | 52 +++--- docs/setup/edu_benefits.md | 22 ++- docs/setup/evss.md | 35 ++-- docs/setup/facilities_locator.md | 14 +- docs/setup/mhv.md | 23 ++- docs/setup/mvi.md | 34 ++-- lib/bb/configuration.rb | 4 +- lib/config_helper.rb | 4 +- lib/evss/base_service.rb | 13 +- lib/evss/claims_service.rb | 2 +- lib/evss/common_service.rb | 2 +- lib/evss/documents_service.rb | 2 +- lib/feature_flipper.rb | 8 +- lib/gi/configuration.rb | 2 +- lib/hca/configuration.rb | 10 +- lib/mvi/configuration.rb | 16 +- lib/mvi/messages/message_builder.rb | 2 +- lib/rx/configuration.rb | 4 +- lib/saml/settings_service.rb | 10 +- lib/sm/configuration.rb | 4 +- .../v0/sessions_controller_spec.rb | 14 +- spec/factories/configurations.rb | 4 +- spec/factories/rubysaml_settings.rb | 16 +- .../create_daily_spool_files_spec.rb | 3 +- .../education_form/writer/factory_spec.rb | 11 +- spec/lib/mvi/configuration_spec.rb | 17 +- spec/lib/mvi/messages/message_builder_spec.rb | 6 +- spec/lib/mvi/service_factory_spec.rb | 46 ++---- spec/lib/saml/saml_settings_service_spec.rb | 8 +- spec/models/mvi_spec.rb | 6 +- spec/rails_helper.rb | 40 ++++- spec/request/saml_metadata_spec.rb | 2 +- spec/spec_helper.rb | 2 +- spec/support/aws_helpers.rb | 38 ++--- spec/support/rx_client_helpers.rb | 2 +- ...disability_claim_document_uploader_spec.rb | 18 +- .../evss_claim_document_uploader_spec.rb | 17 +- 73 files changed, 576 insertions(+), 504 deletions(-) delete mode 100644 config/application.yml.example delete mode 100644 config/health_care_application.yml create mode 100644 config/initializers/config.rb delete mode 100644 config/initializers/figaro.rb create mode 100644 config/initializers/saml.rb delete mode 100644 config/saml.yml create mode 100644 config/settings.yml create mode 100644 config/settings/development.yml create mode 100644 config/settings/production.yml create mode 100644 config/settings/test.yml diff --git a/.gitignore b/.gitignore index 1409bb407d4..644785bb303 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,7 @@ config/application.yml # Ignore .DS_Store .DS_Store + +config/settings.local.yml +config/settings/*.local.yml +config/environments/*.local.yml diff --git a/Gemfile b/Gemfile index 16755763aab..eafb35ddd3f 100644 --- a/Gemfile +++ b/Gemfile @@ -13,6 +13,7 @@ gem 'virtus' #emphasize this is an api only app gem 'rails-api' gem 'figaro' +gem 'config' gem 'pg' gem 'json-schema' gem 'active_model_serializers', '~> 0.10.0' diff --git a/Gemfile.lock b/Gemfile.lock index 62d64158efa..1cdef503196 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -99,6 +99,9 @@ GEM coercible (1.0.0) descendants_tracker (~> 0.0.1) concurrent-ruby (1.0.2) + config (1.4.0) + activesupport (>= 3.0) + deep_merge (~> 1.1.1) connection_pool (2.2.0) crack (0.4.3) safe_yaml (~> 1.0.0) @@ -106,6 +109,7 @@ GEM activemodel activesupport debug_inspector (0.0.2) + deep_merge (1.1.1) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) diff-lcs (1.2.5) @@ -402,6 +406,7 @@ DEPENDENCIES carrierwave (~> 0.11) carrierwave-aws climate_control (= 0.0.3) + config date_validator factory_girl_rails faker diff --git a/Jenkinsfile b/Jenkinsfile index 4695de2727d..293c1196670 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,37 +1,3 @@ -def env_vars = [ - 'RAILS_ENV=test', - 'HOSTNAME=www.example.com', - 'SAML_CERTIFICATE_FILE=spec/support/certificates/ruby-saml.crt', - 'SAML_KEY_FILE=spec/support/certificates/ruby-saml.key', - 'SAML_RELAY=http://localhost:3001/auth/login/callback', - 'SAML_LOGOUT_RELAY=http://localhost:3001/logout', - 'REDIS_HOST=localhost', - 'REDIS_PORT=6379', - 'MHV_HOST=https://mhv-api.example.com', - 'MHV_APP_TOKEN=fake-app-token', - 'DB_ENCRYPTION_KEY=f01ff8ebd1a2b053ad697ae1f0d86adb48ebb708021e4c76c3807d37f6b4e389d5aa45ea171f2f5074222784c1ee2bb8272390d1b9517a7a6987c22733ef00b2', - 'MHV_SM_HOST=https://mhv-api.example.com', - 'MHV_SM_APP_TOKEN=fake-app-token', - 'GIDS_URL=https://dev.vets.gov/gids', - 'EVSS_BASE_URL=https://test.vets.gov', - 'EVSS_SAMPLE_CLAIMANT_USER={"uuid": "1234", "first_name": "Jane", "last_name":"Doe", "edipi": "1105051936", "participant_id": "123456789"}', - 'MVI_URL=http://www.example.com/', - 'MVI_OPEN_TIMEOUT=2', - 'MVI_TIMEOUT=10', - 'MVI_CLIENT_CERT_PATH=/fake/client/cert/path', - 'MVI_CLIENT_KEY_PATH=/fake/client/key/path', - 'MVI_PROCESSING_CODE=T', - 'EVSS_S3_UPLOADS=false', - 'VHA_MAPSERVER_URL=https://services3.arcgis.com/aqgBd3l68G8hEFFE/ArcGIS/rest/services/VHA_Facilities/FeatureServer/0', - 'NCA_MAPSERVER_URL=https://services3.arcgis.com/aqgBd3l68G8hEFFE/ArcGIS/rest/services/NCA_Facilities/FeatureServer/0', - 'VBA_MAPSERVER_URL=https://services3.arcgis.com/aqgBd3l68G8hEFFE/ArcGIS/rest/services/VBA_Facilities/FeatureServer/0', - 'MOCK_MVI_SERVICE=false', - 'GOV_DELIVERY_SERVER=stage-tms.govdelivery.com', - 'ES_URL=https://test.vets.gov', - 'ES_CLIENT_CERT_PATH=/fake/client/cert/path', - 'ES_CLIENT_KEY_PATH=/fake/client/key/path' -] - pipeline { agent { label 'vets-api-linting' @@ -46,7 +12,7 @@ pipeline { stage('Run tests') { steps { sh 'bash --login -c "bundle install --without development -j 4"' - withEnv(env_vars) { + withEnv(['RAILS_ENV=test']) { sh 'bash --login -c "bundle exec rake db:create db:schema:load ci"' } } @@ -59,7 +25,7 @@ pipeline { } } - steps { + steps { build job: 'vets-review-instance-deploy', parameters: [ stringParam(name: 'devops_branch', value: 'master'), stringParam(name: 'api_branch', value: env.BRANCH_NAME), diff --git a/README.md b/README.md index 659b25e258c..cd8cb0ce590 100644 --- a/README.md +++ b/README.md @@ -3,58 +3,77 @@ This project provides common APIs for applications that live on vets.gov. ## Developer Setup -Vets-api requires: -- postgres + +Vets API requires: +- PostgreSQL - Redis -- rails server +- Ruby 2.3 ### Base Setup -To start, fetch this code: `git clone https://github.com/department-of-veterans-affairs/vets-api.git` +To start, fetch this code: + +`git clone https://github.com/department-of-veterans-affairs/vets-api.git` -#### Automated +#### Automated (OSX) -*From the `vets-api` directory, run `./bin/setup-osx && source ~/.bash_profile && cd .` if you're on a mac. It will ensure that you have all development dependencies setup* +If you are developing on OSX, you can run the automated setup script. From +the `vets-api` directory, run `./bin/setup-osx && source ~/.bash_profile && cd .` -#### Alternative -1. Install Ruby 2.3. (It is suggested to use a Ruby version manager such as [rbenv](https://github.com/rbenv/rbenv#installation) and then to [install Ruby 2.3](https://github.com/rbenv/rbenv#installing-ruby-versions)). -*Note*: rbenv will also provide additional installation instructions in the console output. Make sure to follow those too. -1. Install Bundler to manage dependencies: `gem install bundler` -1. Install Postgres (on Mac): `brew install postgres` +#### Alternative (OSX) -1. Install Redis (on Mac): `brew install redis` +1. Install Ruby 2.3. + - It is suggested that you use a Ruby version manager such as + [rbenv](https://github.com/rbenv/rbenv#installation) and + [install Ruby 2.3](https://github.com/rbenv/rbenv#installing-ruby-versions). + - *NOTE*: rbenv will also provide additional installation instructions in the + console output. Make sure to follow those too. +1. Install Bundler to manage dependencies + - `gem install bundler` +1. Install Postgres and enable on startup + - `brew install postgres` + - `brew services start postgres` +1. Install Redis + - `brew install redis` + - Follow post-install instructions to enable Redis on startup. Otherwise, + launch it manually with `brew services start redis`. 1. Install gem dependencies: `cd vets-api; bundle install` 1. Install overcommit `overcommit --install --sign` -1. Create a application.yml `cat ./config/application.yml.example > ./config/application.yml` 1. Setup localhost certificates / keys - - Create a hidden folder in home directory: `mkdir ~/.certs` - - Copy the [certificate](https://github.com/department-of-veterans-affairs/vets.gov-team/blob/master/Products/Identity/Identity%20Discovery%202016/certificates/vetsgov-localhost.crt) to ~/.certs - - Copy the [key](https://github.com/department-of-veterans-affairs/vets.gov-team/blob/master/Products/Identity/Identity%20Discovery%202016/certificates/vetsgov-localhost.key) to ~/.certs + - Create a hidden folder in your home directory: `mkdir ~/.certs` + - Copy the [certificate][certificate] to `~/.certs/vetsgov-localhost.crt` + - Copy the [key][key] to `~/.certs/vetsgov-localhost.key` + - *NOTE*: If you don't have access to these keys, running the following + commands will provide basic functionality, such as for running unit tests: + - `touch ~/.certs/vetsgov-localhost.crt` + - `touch ~/.certs/vetsgov-localhost.key` +1. Create dev database: `bundle exec rake db:setup` -##### Database Setup -1. Start Postgres: `brew services start postgres` -1. Create dev database: `bundle exec rake db:setup` +[certificate]: https://github.com/department-of-veterans-affairs/vets.gov-team/blob/master/Products/Identity/Identity%20Discovery%202016/certificates/vetsgov-localhost.crt +[key]: https://github.com/department-of-veterans-affairs/vets.gov-team/blob/master/Products/Identity/Identity%20Discovery%202016/certificates/vetsgov-localhost.key -##### Redis Setup -You will need to specify the following environment variables in `application.yml`: -``` -REDIS_HOST -REDIS_PORT -``` +### Configuration -For an example, see `application.yml.example` +Vets API is configured with [Config](https://github.com/railsconfig/config). The +default configuration is contained in [settings.yml](config/settings.yml). To +customize your setup, you can create a `config/settings.local.yml` file with +configuration specific to your needs. For example, to configure Redis and +PostgreSQL, place something like this in that file: -1. Follow post install instructions - - always have Redis running as service - - manually launch Redis `brew services start redis` -1. Set the environment variables above according to your Redis configuration +```yaml +database_url: postgres://pg_host:9999/custom_db +redis: + host: redis_host + port: 9999 +``` + +This is also where you will place any other customizations, such as API tokens +or certificate paths. -*Note*: If you encounter `Redis::CannotConnectError: Error connecting to Redis on localhost:6379 (Errno::ECONNREFUSED)` -this is a sign that redis is not currently running or `config/redis.yml` is not using correct host and port. -Tra ### Optional Application Configuration + The following features require additional configuration, click for details. - [Authentication with ID.me](/docs/setup/authentication_with_idme.md) - [EVSS](/docs/setup/evss.md) @@ -63,37 +82,54 @@ The following features require additional configuration, click for details. - [Education Benefits](/docs/setup/edu_benefits.md) - [Master Veteran Index (MVI)](/docs/setup/mvi.md) -Vets-api will still run in a limited capacity without configuring any of the features. +Vets API will still run in a limited capacity without configuring any of these +features, and will run the unit tests successfully. ## Running the App -Manually run each: -1. `postgres -D /usr/local/var/postgres` -1. `redis-server /usr/local/etc/redis.conf` -1. `bundle exec rails server` from /vets-api/ +From within the cloned repo directory, you can run this command to run +`vets-api`: + +``` +bundle exec rails server +``` -#### Running the App with Foreman -1. Start the application: `bundle exec foreman start` -1. Navigate to in your browser. +You can also run `vets-api` with Foreman: + +``` +bundle exec foreman start +``` + +You should then be able to navigate to http://localhost:3000/v0/status in your +browser and start interacting with the API. ### Testing Commands + - `bundle exec rake lint` - Run the full suite of linters on the codebase. -- `bundle exec guard` - Runs the guard test server that reruns your tests after files are saved. Useful for TDD! +- `bundle exec guard` - Runs the guard test server that reruns your tests after + files are saved. Useful for TDD! - `bundle exec rake security` - Run the suite of security scanners on the codebase. - `bundle exec rake ci` - Run all build steps performed in CI. ## Deployment Instructions -Ansible templates and instructions for deploying are in the [devops repo](https://github.com/department-of-veterans-affairs/devops/tree/master/ansible). The `app_name` for this project is `platform-api`. After deploying, you can check that the right version was deployed with: -``` -https://dev-api.vets.gov/v0/status -``` +Jenkins deploys `vets-api` upon each merge to `master`: + +http://jenkins.vetsgov-internal/job/department-of-veterans-affairs/job/vets-api/job/master/ -There is also a [jenkins build](https://dev.vets.gov/jenkins/job/vets_gov_deploy_all/) that will deploy all the apps in a certain environment. +Each deploy is available here: + +https://dev-api.vets.gov/v0/status ## API Request key formatting -When sending HTTP requests use the `X-Key-Inflection` request header to specify which case your client wants to use. Valid cases are `camel`, `dash`, and `snake`. For example if you set `X-Key-Inflection: camel` then you can use camelCase keys in your JSON request body and you will get back data with camelCase keys in the response body. If the header is not provided then the server will expect snake_case keys in the request body and output snake_case in the response. +When sending HTTP requests use the `X-Key-Inflection` request header to specify +which case your client wants to use. Valid cases are `camel`, `dash`, and +`snake`. For example if you set `X-Key-Inflection: camel` then you can use +camelCase keys in your JSON request body and you will get back data with +camelCase keys in the response body. If the header is not provided then the +server will expect snake_case keys in the request body and output snake_case in +the response. ## How to Contribute @@ -101,11 +137,13 @@ There are many ways to contribute to this project: **Bugs** -If you spot a bug, let us know! File a GitHub Issue for this project. When filing an issue add the following: +If you spot a bug, let us know! File a GitHub Issue for this project. When +filing an issue add the following: - Title: Sentence that summarizes the bug concisely - Comment: - - The environment you experienced the bug (browser, browser version, kind of account any extensions enabled) + - The environment you experienced the bug (browser, browser version, kind of + account any extensions enabled) - The exact steps you took that triggered the bug. Steps 1, 2, 3, etc. - The expected outcome - The actual outcome (include screen shot or error logs) @@ -115,9 +153,14 @@ For security related bugs unfit for public viewing, email us feedback@va.gov **Code Submissions** -This project logs all work needed and work being actively worked on via GitHub Issues. Submissions related to these are especially appreciated, but patches and additions outside of these are also great. +This project logs all work needed and work being actively worked on via GitHub +Issues. Submissions related to these are especially appreciated, but patches and +additions outside of these are also great. -If you are working on something related to an existing GitHub Issue that already has an assignee, talk with them first (we don't want to waste your time). If there is no assignee, assign yourself (if you have permissions) or post a comment stating that you're working on it. +If you are working on something related to an existing GitHub Issue that already +has an assignee, talk with them first (we don't want to waste your time). If +there is no assignee, assign yourself (if you have permissions) or post a +comment stating that you're working on it. To work on your code submission, follow [GitHub Flow](https://guides.github.com/introduction/flow/): @@ -127,8 +170,12 @@ To work on your code submission, follow [GitHub Flow](https://guides.github.com/ 1. Discuss via Pull Request 1. Pull Request gets approved or denied by core team member -If you're from the community, it may take one to two weeks to review your pull request. Teams work in one to two week sprints, so they need time to need add it to their time line. +If you're from the community, it may take one to two weeks to review your pull +request. Teams work in one to two week sprints, so they need time to need add it +to their time line. ## Contact -If you have a question or comment about this project, file a GitHub Issue with your question in the Title, any context in the Comment, and add the `question` Label. +If you have a question or comment about this project, file a GitHub Issue with +your question in the Title, any context in the Comment, and add the `question` +Label. diff --git a/app/controllers/v0/sessions_controller.rb b/app/controllers/v0/sessions_controller.rb index d2b5f244cbf..5f979eedf83 100644 --- a/app/controllers/v0/sessions_controller.rb +++ b/app/controllers/v0/sessions_controller.rb @@ -34,13 +34,13 @@ def saml_callback if @saml_response.is_valid? && persist_session_and_user async_create_evss_account(@current_user) - redirect_to SAML_CONFIG['relay'] + '?token=' + @session.token + redirect_to Settings.saml.relay + '?token=' + @session.token obscure_token = Session.obscure_token(@session.token) Rails.logger.info("Logged in user with id #{@session.uuid}, token #{obscure_token}") else handle_login_error - redirect_to SAML_CONFIG['relay'] + '?auth=fail' + redirect_to Settings.saml.relay + '?auth=fail' end end @@ -82,12 +82,12 @@ def handle_completed_slo if errors.size.positive? extra_context = { in_response_to: logout_response&.in_response_to } log_to_sentry("SAML Logout failed!\n " + errors.join("\n "), :error, extra_context) - redirect_to SAML_CONFIG['logout_relay'] + '?success=false' + redirect_to Settings.saml.logout_relay + '?success=false' else logout_request.destroy session.destroy user.destroy - redirect_to SAML_CONFIG['logout_relay'] + '?success=true' + redirect_to Settings.saml.logout_relay + '?success=true' # even if mhv logout raises exception, still consider logout successful from browser POV MHVLoggingService.logout(user) end @@ -112,7 +112,7 @@ def log_to_sentry(message, level, context = {}) end def saml_options - ENV['REVIEW_INSTANCE_SLUG'].blank? ? {} : { RelayState: ENV['REVIEW_INSTANCE_SLUG'] } + Settings.review_instance_slug.blank? ? {} : { RelayState: Settings.review_instance_slug } end end end diff --git a/app/mailers/year_to_date_report_mailer.rb b/app/mailers/year_to_date_report_mailer.rb index 775fafcc72b..e96dcf70f46 100644 --- a/app/mailers/year_to_date_report_mailer.rb +++ b/app/mailers/year_to_date_report_mailer.rb @@ -45,14 +45,14 @@ def build(report_file) private def s3_bucket - ENV['REPORTS_AWS_S3_BUCKET'] + Settings.reports.aws.bucket end def new_s3_resource Aws::S3::Resource.new( - region: ENV['REPORTS_AWS_S3_REGION'], - access_key_id: ENV['REPORTS_AWS_ACCESS_KEY_ID'], - secret_access_key: ENV['REPORTS_AWS_SECRET_ACCESS_KEY'] + region: Settings.reports.aws.region, + access_key_id: Settings.reports.aws.access_key_id, + secret_access_key: Settings.reports.aws.secret_access_key ) end end diff --git a/app/models/education_benefits_claim.rb b/app/models/education_benefits_claim.rb index 2e4462fad27..8d82fa58519 100644 --- a/app/models/education_benefits_claim.rb +++ b/app/models/education_benefits_claim.rb @@ -14,7 +14,7 @@ class EducationBenefitsClaim < ActiveRecord::Base has_one(:education_benefits_submission, inverse_of: :education_benefits_claim) - attr_encrypted(:form, key: ENV['DB_ENCRYPTION_KEY']) + attr_encrypted(:form, key: Settings.db_encryption_key) # initially only completed claims are allowed, later we can allow claims that dont have a submitted_at yet before_validation(:set_submitted_at, on: :create) diff --git a/app/models/in_progress_form.rb b/app/models/in_progress_form.rb index 038c18b3151..f70e4fc3b8a 100644 --- a/app/models/in_progress_form.rb +++ b/app/models/in_progress_form.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class InProgressForm < ActiveRecord::Base - attr_encrypted :form_data, key: ENV['DB_ENCRYPTION_KEY'] + attr_encrypted :form_data, key: Settings.db_encryption_key def self.form_for_user(form_id, user) InProgressForm.find_by(form_id: form_id, user_uuid: user.uuid) diff --git a/app/models/mvi.rb b/app/models/mvi.rb index d30408d56ff..9afea6320a2 100644 --- a/app/models/mvi.rb +++ b/app/models/mvi.rb @@ -76,7 +76,7 @@ def mvi_response end def mvi_service - @service ||= MVI::ServiceFactory.get_service(mock_service: ENV['MOCK_MVI_SERVICE']) + @service ||= MVI::ServiceFactory.get_service(mock_service: Settings.mvi.mock) end def create_message diff --git a/app/models/nca_facility_adapter.rb b/app/models/nca_facility_adapter.rb index 691e9991279..dcf01455fad 100644 --- a/app/models/nca_facility_adapter.rb +++ b/app/models/nca_facility_adapter.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # frozen_string_literal: true class NCAFacilityAdapter - NCA_URL = +ENV['NCA_MAPSERVER_URL'] + NCA_URL = +Settings.locators.nca NCA_ID_FIELD = 'CEMETERY_I' FACILITY_TYPE = 'va_cemetery' diff --git a/app/models/vba_facility_adapter.rb b/app/models/vba_facility_adapter.rb index 90243275117..d3fa71c4ac9 100644 --- a/app/models/vba_facility_adapter.rb +++ b/app/models/vba_facility_adapter.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class VBAFacilityAdapter - VBA_URL = +ENV['VBA_MAPSERVER_URL'] + VBA_URL = +Settings.locators.vba VBA_ID_FIELD = 'Facility_Number' FACILITY_TYPE = 'va_benefits_facility' diff --git a/app/models/vha_facility_adapter.rb b/app/models/vha_facility_adapter.rb index fdbc994ea50..83b108165e2 100644 --- a/app/models/vha_facility_adapter.rb +++ b/app/models/vha_facility_adapter.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true class VHAFacilityAdapter - VHA_URL = +ENV['VHA_MAPSERVER_URL'] + VHA_URL = +Settings.locators.vha VHA_ID_FIELD = 'StationNumber' FACILITY_TYPE = 'va_health_facility' diff --git a/app/uploaders/disability_claim_document_uploader.rb b/app/uploaders/disability_claim_document_uploader.rb index 30f81fccede..9fba4c23fd9 100644 --- a/app/uploaders/disability_claim_document_uploader.rb +++ b/app/uploaders/disability_claim_document_uploader.rb @@ -33,12 +33,12 @@ def validate_file_size(file) end def set_storage_options! - if ENV['EVSS_S3_UPLOADS'] == 'true' + if Settings.evss.s3.uploads_enabled self.aws_credentials = { - region: ENV['EVSS_AWS_S3_REGION'] + region: Settings.evss.s3.region } self.aws_acl = 'private' - self.aws_bucket = ENV['EVSS_AWS_S3_BUCKET'] + self.aws_bucket = Settings.evss.s3.bucket self.aws_attributes = { server_side_encryption: 'AES256' } self.class.storage = :aws else diff --git a/app/uploaders/evss_claim_document_uploader.rb b/app/uploaders/evss_claim_document_uploader.rb index ccb5feb8a80..db1c988e03c 100644 --- a/app/uploaders/evss_claim_document_uploader.rb +++ b/app/uploaders/evss_claim_document_uploader.rb @@ -33,12 +33,12 @@ def validate_file_size(file) end def set_storage_options! - if ENV['EVSS_S3_UPLOADS'] == 'true' + if Settings.evss.s3.uploads_enabled self.aws_credentials = { - region: ENV['EVSS_AWS_S3_REGION'] + region: Settings.evss.s3.region } self.aws_acl = 'private' - self.aws_bucket = ENV['EVSS_AWS_S3_BUCKET'] + self.aws_bucket = Settings.evss.s3.bucket self.aws_attributes = { server_side_encryption: 'AES256' } self.class.storage = :aws else diff --git a/app/workers/education_form/writer/factory.rb b/app/workers/education_form/writer/factory.rb index 9f458e4d144..cc11f9b929d 100644 --- a/app/workers/education_form/writer/factory.rb +++ b/app/workers/education_form/writer/factory.rb @@ -2,10 +2,10 @@ module EducationForm class Writer::Factory def self.get_writer - if Rails.env.development? || ENV['EDU_SFTP_HOST'].blank? + if Rails.env.development? || Settings.edu.sftp.host.blank? EducationForm::Writer::Local - elsif ENV['EDU_SFTP_PASS'].blank? - raise "EDU_SFTP_PASS not set for #{ENV['EDU_SFTP_USER']}@#{ENV['EDU_SFTP_HOST']}" + elsif Settings.edu.sftp.pass.blank? + raise "Settings.edu.sftp.pass not set for #{Settings.edu.sftp.user}@#{Settings.edu.sftp.host}" else EducationForm::Writer::Remote end diff --git a/app/workers/education_form/writer/remote.rb b/app/workers/education_form/writer/remote.rb index 3eaadc3d314..88e7eae2f24 100644 --- a/app/workers/education_form/writer/remote.rb +++ b/app/workers/education_form/writer/remote.rb @@ -8,7 +8,7 @@ def initialize(logger:) def sftp @sftp ||= begin @logger.info('Connected to SFTP') - Net::SFTP.start(ENV['EDU_SFTP_HOST'], ENV['EDU_SFTP_USER'], password: ENV['EDU_SFTP_PASS']) + Net::SFTP.start(Settings.edu.sftp.host, Settings.edu.sftp.user, password: Settings.edu.sftp.pass) end end diff --git a/config/application.rb b/config/application.rb index 8daaba137be..28d7b84f692 100644 --- a/config/application.rb +++ b/config/application.rb @@ -32,6 +32,8 @@ class Application < Rails::Application config.api_only = true + config.relative_url_root = Settings.relative_url_root + # This prevents rails from escaping html like & in links when working with JSON config.active_support.escape_html_entities_in_json = false @@ -40,7 +42,7 @@ class Application < Rails::Application # CORS configuration; see also cors_preflight route config.middleware.insert_before 0, 'Rack::Cors', logger: (-> { Rails.logger }) do allow do - origins { |source, _env| ENV['WEB_ORIGIN'].split(',').include?(source) } + origins { |source, _env| Settings.web_origin.split(',').include?(source) } resource '*', headers: :any, methods: :any, credentials: true diff --git a/config/application.yml.example b/config/application.yml.example deleted file mode 100644 index 12adcfb9352..00000000000 --- a/config/application.yml.example +++ /dev/null @@ -1,35 +0,0 @@ -# These are local environment settings that will get picked up as environment variables -# by the Figaro gem. -# Change to match your local settings and save the file as application.yml - -HOSTNAME: www.example.com # This is used by json links, could be used elsewhere if we want -SAML_CERTIFICATE_FILE: ~/.certs/vetsgov-localhost.crt -SAML_KEY_FILE: ~/.certs/vetsgov-localhost.key -REDIS_HOST: localhost -REDIS_PORT: "6379" -MHV_HOST: 'https://mhv-api.example.com' -MHV_APP_TOKEN: 'fake-app-token' -DB_ENCRYPTION_KEY: 'f01ff8ebd1a2b053ad697ae1f0d86adb48ebb708021e4c76c3807d37f6b4e389d5aa45ea171f2f5074222784c1ee2bb8272390d1b9517a7a6987c22733ef00b2' -MHV_SM_HOST: 'https://mhv-api.example.com' -MHV_SM_APP_TOKEN: 'fake-app-token' -GIDS_URL: 'https://dev.vets.gov/gids' -EVSS_BASE_URL: 'https://test.vets.gov' -EVSS_S3_UPLOADS: 'false' -VHA_MAPSERVER_URL: 'https://services3.arcgis.com/aqgBd3l68G8hEFFE/ArcGIS/rest/services/VHA_Facilities/FeatureServer/0' -NCA_MAPSERVER_URL: 'https://services3.arcgis.com/aqgBd3l68G8hEFFE/ArcGIS/rest/services/NCA_Facilities/FeatureServer/0' -VBA_MAPSERVER_URL: 'https://services3.arcgis.com/aqgBd3l68G8hEFFE/ArcGIS/rest/services/VBA_Facilities/FeatureServer/0' -MVI_URL: 'http://see.project.readme.for.instructions.org/' -MVI_OPEN_TIMEOUT: '2' -MVI_TIMEOUT: '10' -MVI_CLIENT_CERT_PATH: '/fake/client/cert/path' -MVI_CLIENT_KEY_PATH: '/fake/client/key/path' -MVI_PROCESSING_CODE: 'T' -MOCK_MVI_SERVICE: 'true' -GOV_DELIVERY_SERVER: stage-tms.govdelivery.com - -ES_URL: 'https://test.vets.gov' -ES_CLIENT_CERT_PATH: '/fake/client/cert/path' -ES_CLIENT_KEY_PATH: '/fake/client/key/path' - -# For CORS requests; separate multiple origins with a comma -WEB_ORIGIN: 'http://localhost:3000,http://localhost:3001' diff --git a/config/database.yml b/config/database.yml index 70d8e81fca7..9d29b79b0f2 100644 --- a/config/database.yml +++ b/config/database.yml @@ -22,8 +22,7 @@ default: &default pool: 5 development: - <<: *default - database: vets_api_development + url: <%= Settings.database_url %> # The specified database role being used to connect to postgres. # To create additional roles in postgres see `$ createuser --help`. @@ -56,8 +55,7 @@ development: # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: - <<: *default - database: vets_api_test + url: <%= Settings.database_url %> # As with config/secrets.yml, you never want to store sensitive information, # like your database password, in your source code. If your source code is @@ -79,5 +77,4 @@ test: # url: <%= ENV['DATABASE_URL'] %> # production: - <<: *default - database: vets_api_production + url: <%= Settings.database_url %> diff --git a/config/environments/development.rb b/config/environments/development.rb index e4b09406a97..ef2198497e3 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -3,7 +3,7 @@ Rails.application.configure do # Specify environment specific hostname and protocol - config.hostname = ENV['HOSTNAME'] + config.hostname = Settings.hostname config.protocol = 'http' routes.default_url_options = { host: config.hostname, protocol: config.protocol } # Settings specified here will take precedence over those in config/application.rb. diff --git a/config/environments/production.rb b/config/environments/production.rb index 448ecfb0771..634daca23f8 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -3,7 +3,7 @@ Rails.application.configure do # Specify environment specific hostname and protocol - config.hostname = ENV['HOSTNAME'] + config.hostname = Settings.hostname config.protocol = 'https' routes.default_url_options = { host: config.hostname, protocol: config.protocol } # Settings specified here will take precedence over those in config/application.rb. diff --git a/config/environments/test.rb b/config/environments/test.rb index ddbdccf5c84..6959fba0a79 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -2,7 +2,7 @@ Rails.application.configure do # Specify environment specific hostname and protocol - config.hostname = ENV['HOSTNAME'] + config.hostname = Settings.hostname config.protocol = 'http' routes.default_url_options = { host: config.hostname, protocol: config.protocol } # Settings specified here will take precedence over those in config/application.rb. diff --git a/config/health_care_application.yml b/config/health_care_application.yml deleted file mode 100644 index 266793adfec..00000000000 --- a/config/health_care_application.yml +++ /dev/null @@ -1,26 +0,0 @@ -endpoints: - esSqa: &es_sqa 'https://vaww.esrstage1a.aac.va.gov/voa/voaSvc' - esDev: &es_dev 'https://vaww.esrdev30.aac.va.gov:8433/voa/voaSvc?wsdl' - esPreprod: &pre_prod 'https://vaww.esrpre-prod.aac.va.gov/voa/voaSvc' - esProd: &prod 'https://vaww.esr.aac.va.gov/voa/voaSvc' - -trust_chains: - internal: &internal - - 'VA Internal Subordinate CA 1.pem' - - 'VA Internal Root CA.pem' - common: &common - - 'Veterans Affairs Device CA B2.pem' - - 'Betrusted Production SSP CA A1.pem' - - 'Federal Common Policy CA.pem' - -test: - endpoint: *es_dev - ca: *common - -development: - endpoint: *es_dev - ca: *common - -production: - endpoint: <%= ENV['ES_URL'] %> - ca: ~ diff --git a/config/initializers/config.rb b/config/initializers/config.rb new file mode 100644 index 00000000000..3146c397c69 --- /dev/null +++ b/config/initializers/config.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +Config.setup do |config| + # Name of the constant exposing loaded settings + config.const_name = 'Settings' + + # Ability to remove elements of the array set in earlier loaded settings file. For example value: '--'. + # + # config.knockout_prefix = nil + + # Overwrite arrays found in previously loaded settings file. When set to `false`, arrays will be merged. + # + # config.overwrite_arrays = true + + # Load environment variables from the `ENV` object and override any settings defined in files. + # + # config.use_env = false + + # Define ENV variable prefix deciding which variables to load into config. + # + # config.env_prefix = 'Settings' + + # What string to use as level separator for settings loaded from ENV variables. Default value of '.' works well + # with Heroku, but you might want to change it for example for '__' to easy override settings from command line, where + # using dots in variable names might not be allowed (eg. Bash). + # + # config.env_separator = '.' + + # Ability to process variables names: + # * nil - no change + # * :downcase - convert to lower case + # + # config.env_converter = :downcase + + # Parse numeric values as integers instead of strings. + # + # config.env_parse_values = true +end diff --git a/config/initializers/figaro.rb b/config/initializers/figaro.rb deleted file mode 100644 index 69736333e54..00000000000 --- a/config/initializers/figaro.rb +++ /dev/null @@ -1,38 +0,0 @@ -# frozen_string_literal: true -Figaro.require_keys( - 'HOSTNAME', - 'SAML_CERTIFICATE_FILE', - 'SAML_KEY_FILE', - 'REDIS_HOST', - 'REDIS_PORT', - 'DB_ENCRYPTION_KEY', - 'MHV_HOST', - 'MHV_APP_TOKEN', - 'MHV_SM_HOST', - 'MHV_SM_APP_TOKEN', - 'GIDS_URL', - 'EVSS_BASE_URL', - 'MVI_URL', - 'MVI_CLIENT_CERT_PATH', - 'MVI_CLIENT_KEY_PATH', - 'EVSS_S3_UPLOADS', - 'VHA_MAPSERVER_URL', - 'NCA_MAPSERVER_URL', - 'VBA_MAPSERVER_URL', - 'GOV_DELIVERY_SERVER', - 'ES_URL', - 'ES_CLIENT_CERT_PATH', - 'ES_CLIENT_KEY_PATH' -) - -if Rails.env.production? - Figaro.require_keys( - 'REPORTS_AWS_ACCESS_KEY_ID', - 'REPORTS_AWS_SECRET_ACCESS_KEY', - 'REPORTS_AWS_S3_REGION', - 'REPORTS_AWS_S3_BUCKET', - 'EDU_SFTP_HOST', - 'EDU_SFTP_USER', - 'EDU_SFTP_PASS' - ) -end diff --git a/config/initializers/override_redirect_to_logging.rb b/config/initializers/override_redirect_to_logging.rb index 733fed32f59..ac9649ff287 100644 --- a/config/initializers/override_redirect_to_logging.rb +++ b/config/initializers/override_redirect_to_logging.rb @@ -15,11 +15,10 @@ def unsubscribe(log_subscriber, event_component) end # Add our custom log subscriber for redirect_to -SAML_CONFIG = Rails.application.config_for(:saml).freeze class FilteredLogSubscriber < ActiveSupport::LogSubscriber def redirect_to(event) - if event.payload[:location].include?(SAML_CONFIG['relay'] + '?token=') - info { "Redirected to #{SAML_CONFIG['relay']} with token" } + if event.payload[:location].include?(Settings.saml.relay + '?token=') + info { "Redirected to #{Settings.saml.relay} with token" } else info { "Redirected to #{event.payload[:location]}" } end diff --git a/config/initializers/saml.rb b/config/initializers/saml.rb new file mode 100644 index 00000000000..9545bbe44df --- /dev/null +++ b/config/initializers/saml.rb @@ -0,0 +1,3 @@ +# frozen_string_literal: true +Settings.saml.certificate = File.read(File.expand_path(Settings.saml.cert_path)) +Settings.saml.key = File.read(File.expand_path(Settings.saml.key_path)) diff --git a/config/mvi_schema/IdmWebService_200VGOV.wsdl.erb b/config/mvi_schema/IdmWebService_200VGOV.wsdl.erb index 8ccea434033..cf4522f5d97 100755 --- a/config/mvi_schema/IdmWebService_200VGOV.wsdl.erb +++ b/config/mvi_schema/IdmWebService_200VGOV.wsdl.erb @@ -139,7 +139,7 @@ + location="<%= Settings.mvi.url %>" /> diff --git a/config/redis.yml b/config/redis.yml index 875b16ea67a..09398ce20a8 100644 --- a/config/redis.yml +++ b/config/redis.yml @@ -1,7 +1,7 @@ development: &defaults redis: - host: <%= ENV["REDIS_HOST"] %> - port: <%= ENV["REDIS_PORT"] %> + host: <%= Settings.redis.host %> + port: <%= Settings.redis.port %> session_store: namespace: vets-api-session each_ttl: 3600 diff --git a/config/saml.yml b/config/saml.yml deleted file mode 100644 index 68547fadde7..00000000000 --- a/config/saml.yml +++ /dev/null @@ -1,22 +0,0 @@ -development: &defaults - issuer: saml-rp.vetsgov.localhost - callback_url: http://localhost:3000/auth/saml/callback - metadata_url: https://api.idmelabs.com/saml/metadata/provider - certificate: <%= File.read(File.expand_path(ENV["SAML_CERTIFICATE_FILE"])).dump %> - key: <%= File.read(File.expand_path(ENV['SAML_KEY_FILE'])).dump %> - relay: http://localhost:3001/auth/login/callback - logout_relay: http://localhost:3001/logout - -test: - <<: *defaults - certificate: <%= File.read("spec/support/certificates/ruby-saml.crt").dump %> - key: <%= File.read("spec/support/certificates/ruby-saml.key").dump %> - -production: - issuer: <%= ENV["SAML_ISSUER"] %> - callback_url: <%=ENV["CALLBACK_URL"] %> - metadata_url: <%= ENV["METADATA_URL"] %> - certificate: <%= File.read(File.expand_path(ENV["SAML_CERTIFICATE_FILE"])).dump %> - key: <%= File.read(File.expand_path(ENV["SAML_KEY_FILE"])).dump %> - relay: <%= ENV["SAML_RELAY"] %> - logout_relay: <%= ENV["SAML_LOGOUT_RELAY"] %> diff --git a/config/secrets.yml b/config/secrets.yml index 2706d07fcab..a1e2541977f 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -11,12 +11,12 @@ # if you're sharing your code publicly. development: - secret_key_base: 8af0fe1e378586520e4324694897eb269bd0fffa1c5be6cc3b4ffb9dbde095d0bef5c7fdab73cd05685d8fe1dd589287d78b38e4de7116fbe14461e414072677 + secret_key_base: <%= Settings.secret_key_base %> test: - secret_key_base: be8e6b6b16993e899c2c4fd08f7c6a6e5ad5f295b369d22f126d4569d2a0e44c4f04b13c02d65ab701452ef0a24ed2db7af441214ed5ae98c6113442f5846605 + secret_key_base: <%= Settings.secret_key_base %> # Do not keep production secrets in the repository, # instead read values from the environment. production: - secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> + secret_key_base: <%= Settings.secret_key_base %> diff --git a/config/settings.yml b/config/settings.yml new file mode 100644 index 00000000000..bc30666438c --- /dev/null +++ b/config/settings.yml @@ -0,0 +1,101 @@ +hostname: www.example.com + +# For CORS requests; separate multiple origins with a comma +web_origin: http://localhost:3000,http://localhost:3001 + +db_encryption_key: f01ff8ebd1a2b053ad697ae1f0d86adb48ebb708021e4c76c3807d37f6b4e389d5aa45ea171f2f5074222784c1ee2bb8272390d1b9517a7a6987c22733ef00b2 + +database_url: postgres:///vets-api + +relative_url_root: / + +secret_key_base: 8af0fe1e378586520e4324694897eb269bd0fffa1c5be6cc3b4ffb9dbde095d0bef5c7fdab73cd05685d8fe1dd589287d78b38e4de7116fbe14461e414072677 + +review_instance_slug: ~ + +# Settings for Education Benefits +edu: + show_form: true + sftp: + host: ~ + pass: ~ + user: ~ + +# Settings for EVSS +evss: + url: https://test.vets.gov + cert_path: ~ + key_path: ~ + root_cert_path: ~ + s3: + uploads_enabled: false + bucket: evss_s3_bucket + region: evss_s3_region + +# Settings for GI Bill Data Service +gids: + url: https://dev.vets.gov/gids + +# Settings for Healthcare Application +hca: + endpoint: https://test-foo.vets.gov + cert_path: /fake/client/cert/path + key_path: /fake/client/key/path + ca: + - 'Veterans Affairs Device CA B2.pem' + - 'Betrusted Production SSP CA A1.pem' + - 'Federal Common Policy CA.pem' + +# Settings for the facility locator +locators: + vha: https://services3.arcgis.com/aqgBd3l68G8hEFFE/ArcGIS/rest/services/VHA_Facilities/FeatureServer/0 + nca: https://services3.arcgis.com/aqgBd3l68G8hEFFE/ArcGIS/rest/services/NCA_Facilities/FeatureServer/0 + vba: https://services3.arcgis.com/aqgBd3l68G8hEFFE/ArcGIS/rest/services/VBA_Facilities/FeatureServer/0 + +# Settings for MyHealthEVet +mhv: + rx: + host: https://mhv-api.example.com + app_token: fake-app-token + sm: + host: https://mhv-api.example.com + app_token: fake-app-token + +# Settings for Master Veteran Index +mvi: + url: http://see.project.readme.for.instructions.org/ + open_timeout: 2 + timeout: 10 + mock: true + processing_code: T + client_cert_path: /fake/client/cert/path + client_key_path: /fake/client/key/path + +# Settings for Redis +# TODO(knkski): Move all redis settings here? +redis: + host: localhost + port: 6379 + +# Settings for Education Benefits report uploading +reports: + server: stage-tms.govdelivery.com + token: ~ + aws: + access_key_id: ~ + bucket: ~ + region: ~ + secret_access_key: ~ + +# Settings for SAML authentication +saml: + cert_path: ~/.certs/vetsgov-localhost.crt + key_path: ~/.certs/vetsgov-localhost.key + # Loaded in `config/initializers/saml.rb`, based on `*_path` settings above + # certificate: ~ + # key: ~ + issuer: saml-rp.vetsgov.localhost + callback_url: http://localhost:3000/auth/saml/callback + metadata_url: https://api.idmelabs.com/saml/metadata/provider + relay: http://localhost:3001/auth/login/callback + logout_relay: http://localhost:3001/logout diff --git a/config/settings/development.yml b/config/settings/development.yml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/config/settings/production.yml b/config/settings/production.yml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/config/settings/test.yml b/config/settings/test.yml new file mode 100644 index 00000000000..2957933c3ff --- /dev/null +++ b/config/settings/test.yml @@ -0,0 +1,16 @@ +secret_key_base: be8e6b6b16993e899c2c4fd08f7c6a6e5ad5f295b369d22f126d4569d2a0e44c4f04b13c02d65ab701452ef0a24ed2db7af441214ed5ae98c6113442f5846605 + +mvi: + url: http://www.example.com/ + mock: false + +reports: + aws: + access_key_id: key + bucket: bucket + region: region + secret_access_key: secret + +saml: + cert_path: spec/support/certificates/ruby-saml.crt + key_path: spec/support/certificates/ruby-saml.key diff --git a/docs/setup/authentication_with_idme.md b/docs/setup/authentication_with_idme.md index 541c111093a..2cdbaeae476 100644 --- a/docs/setup/authentication_with_idme.md +++ b/docs/setup/authentication_with_idme.md @@ -1,38 +1,52 @@ ## Vets-API ID.me Certificate Setup -Many of the API's are protected by a session token from ID.me. In order to obtain this token, one must perform authentication through ID.me. This authentication flow only works of the ID.me certificates -are properly configured within vets-api. -The following environment variables must be set (see `application.yml.example`): -``` -CERTIFICATE_FILE -KEY_FILE -``` +Many of the APIs are protected by a session token from ID.me. In order to obtain +this token, one must perform authentication through ID.me. This authentication +flow requires that the ID.me certificates are properly configured within +`vets-api`. -For local development, ID.me has configured their sandbox with a cert that developers can share. +The [README](../README.md) contains instructions for installing a certificate +that will work for local development. If your setup differs from this, customize +the `config/settings.local.yml` file with suitable configuration. For example, -1. Download the [key and certificate files](https://github.com/department-of-veterans-affairs/platform-team/tree/master/identity/certificates) -1. Set the environment variables above to point to your local copies of the files +```yaml +saml: + cert_path: /path/to/cert + key_path: /path/to/key +``` + +See [config/settings.yml](config/settings.yml) for all of the configuration +options. ## Manually Testing ID.me Authentication Flow + Note the following two endpoints: + ``` curl localhost:3000/v0/status # does not require a session token curl localhost:3000/v0/welcome # requires a session token ``` -The default callback from ID.me is configured to go to `http://localhost:3001/auth/login/callback`, which is a front-end route in production. To test just the API locally, without running the vets-website server, start the vets-api server on port 3001: -``` -bundle exec rails s -p 3001 -``` +The default callback from ID.me is configured to go to +`http://localhost:3001/auth/login/callback`, which is a front-end route in +production. To test just the API locally, without running the vets-website +server, start by running the `vets-api` server on port 3001 with +`bundle exec rails s -p 3001`, then: + 1. Curl or browse to `http://localhost:3001/v0/sessions/new` 2. Copy and paste the ID.me URL into your browser. -3. Enter ID.me credentials (Create your ID.me account if you have not already done so. **Note**: creating your account on the ID.me site (https://api.id.me/) is separate from the sandbox (https://api.idmelabs.com) or sign in with your username and password.) -4. The browser should get redirected to `SAML_CONFIG['relay']` (default: http://localhost:3001/auth/login/callback?token=abcd1234-efgh5678) +3. Enter ID.me credentials + - Create your ID.me account if you have not already done so, or sign in with + your username and password. + - **Note**: Accounts created on the https://api.id.me/ ID.me site are + separate from accounts created in the https://api.idmelabs.com sandbox. +4. The browser should get redirected to the SAML relay URL + - Defaults to http://localhost:3001/auth/login/callback?token=abcd1234-efgh5678 5. Copy the token value and attempt the following curl commands: ``` -curl --header "Authorization: Token token=GvmkAW231VxGHkYxyppr2QQsi1D7PStqeiJXyyja" localhost:3001/v0/sessions/current -curl --header "Authorization: Token token=GvmkAW231VxGHkYxyppr2QQsi1D7PStqeiJXyyja" localhost:3001/v0/profile +curl --header "Authorization: Token token=foo" localhost:3001/v0/sessions/current +curl --header "Authorization: Token token=foo" localhost:3001/v0/profile ``` -A valid JSON response to either of these authenticated calls means you succeeded! \ No newline at end of file +A valid JSON response to either of these authenticated calls means you succeeded! diff --git a/docs/setup/edu_benefits.md b/docs/setup/edu_benefits.md index 22c5d9d3d3e..a194363da66 100644 --- a/docs/setup/edu_benefits.md +++ b/docs/setup/edu_benefits.md @@ -1,10 +1,16 @@ ## Education Benefits Year to Date Report -The year to date report uses GovDelivery to send the email and S3 to upload a link to the generated csv file. -To test sending the report, set the following ENV variables within `application.yml` (see application.yml.example): + +The year to date report uses GovDelivery to send the email and S3 to upload a +link to the generated CSV file. To test sending the report, copy the following +configuration into `config/settings.local.yml` with the appropriate values +filled in: + +```yaml +reports: + token: ... + aws: + access_key_id: ... + secret_access_key: ... + region: ... + bucket: ... ``` -GOV_DELIVERY_TOKEN -REPORTS_AWS_ACCESS_KEY_ID -REPORTS_AWS_SECRET_ACCESS_KEY -REPORTS_AWS_S3_REGION -REPORTS_AWS_S3_BUCKET -``` \ No newline at end of file diff --git a/docs/setup/evss.md b/docs/setup/evss.md index ed1566f56d6..1867d0c9fdf 100644 --- a/docs/setup/evss.md +++ b/docs/setup/evss.md @@ -1,23 +1,26 @@ ## EVSS S3 Uploads -Uploaded disability claim documents are handled by CarrierWave and either sent to Amazon S3 or saved to disk. -To enable S3 uploads, set the following ENV variables: -``` -EVSS_S3_UPLOADS -EVSS_AWS_S3_REGION -EVSS_AWS_S3_BUCKET -EVSS_AWS_ACCESS_KEY_ID -EVSS_AWS_SECRET_ACCESS_KEY -``` -Note: `EVSS_S3_UPLOADS` needs to be set to the string 'true' to enable S3 uploads +Uploaded disability claim documents are handled by CarrierWave and either sent +to Amazon S3 or saved to disk. To enable S3 uploads, copy the following +configuration into `config/settings.local.yml` with the appropriate values: +```yaml +evss: + s3: + uploads_enabled: true + bucket: ... + region: ... +``` ## EVSS Disability Claims Setup -For this app to be properly configured, you will need to specify the following environment variables: -``` -EVSS_BASE_URL -EVSS_SAMPLE_CLAIMANT_USER + +For this app to be properly configured, you will need to copy the following +configuration into `config/settings.local.yml` with the appropriate URL: + +```yaml +evss: + url: ... ``` -For an example, see `application.yml.example` - these are just mock endpoints. -For actual backend testing you will need to reference the appropriate private repository. +The `config/settings.yml` file contains an example mock endpoint. For actual +backend testing, you will need to reference the appropriate private repository. diff --git a/docs/setup/facilities_locator.md b/docs/setup/facilities_locator.md index e805c4ac89f..11545c98bac 100644 --- a/docs/setup/facilities_locator.md +++ b/docs/setup/facilities_locator.md @@ -1,12 +1,6 @@ ### Facilities Locator Setup -For this app to be properly configured, you need the following environment variables: -``` -VHA_MAPSERVER_URL -VHA_MAPSERVER_LAYER -``` -For an example, see `application.yml.example`. - -For the current maps.va.gov endpoint, you will need to add the VA internal root CA -certificate to your trusted certificates. With homebrew this is typically done by -appending the exported/downloaded certificate to `/etc/openssl/cert.pem`. \ No newline at end of file +For the current maps.va.gov endpoint, you will need to add the VA internal root +CA certificate to your trusted certificates. With `homebrew` this is typically +done by appending the exported/downloaded certificate to +`/etc/openssl/cert.pem`. diff --git a/docs/setup/mhv.md b/docs/setup/mhv.md index 488decfac41..eb54ebcec78 100644 --- a/docs/setup/mhv.md +++ b/docs/setup/mhv.md @@ -1,11 +1,18 @@ ## MHV Prescriptions and MHV Secure Messaging Setup -Prescription refill and secure-messaging require a working MHV (MyHealthEVet) config. You will need to specify the following environment variables: -``` -MHV_HOST -MHV_APP_TOKEN -MHV_SM_HOST -MHV_SM_APP_TOKEN + +Prescription refill and secure-messaging require a working MHV (MyHealthEVet) +config. You will need to copy the following configuration into +`config/settings.local.yml` with the appropriate values filled in. + +```yaml +mhv: + rx: + host: ... + app_token: ... + sm: + host: ... + app_token: ... ``` -For an example, see `application.yml.example` - these are just mock endpoints. -For actual backend testing you will need to reference the appropriate private repository. \ No newline at end of file +The `config/settings.yml` file contains example mock endpoints. For actual +backend testing, you will need to reference the appropriate private repository. diff --git a/docs/setup/mvi.md b/docs/setup/mvi.md index e4fda2efcb3..37bf93f437e 100644 --- a/docs/setup/mvi.md +++ b/docs/setup/mvi.md @@ -1,20 +1,28 @@ ## MVI Service -The Master Veteran Index Service retreives and updates a veterans 'golden record'. -Update the `MVI_URL` env var in config/application.yml with the value given to you -by devops or your team. + +The Master Veteran Index service retrieves and updates a veteran's 'golden +record'. To configure `vets-api` for use with MVI, configure +`config/settings.local.yml` with the settings given to you by devops or your +team. For example, + ``` -# config/application.yml -MVI_URL = '...' +# config/settings.local.yml +mvi: + url: ... ``` -Since that URL is only accessible over the VA VPN a mock service is included in the project. -To enable it set MOCK_MVI_SERVICE in config/application.yml to 'true' + +Since that URL is only accessible over the VA VPN a mock service is included in +the project. To enable it, add this to `config/settings.local.yml`: + ``` -# config/application.yml -MOCK_MVI_SERVICE = true +mvi: + mock: true ``` -Endpoint response values can be set by copying mock_mvi_responses.yml.example to -mock_mvi_responses.yml. For the find_candidate -endpoint you can return different responses based on SSN: + +Endpoint response values can be set by copying `mock_mvi_responses.yml.example` +to `mock_mvi_responses.yml`. For the `find_candidate` endpoint you can return +different responses based on SSN: + ``` find_candidate: 555443333: @@ -29,4 +37,4 @@ find_candidate: status: 'active' 111223333: # another mock response hash here... -``` \ No newline at end of file +``` diff --git a/lib/bb/configuration.rb b/lib/bb/configuration.rb index 2b34a18faa9..c6af622c1c9 100644 --- a/lib/bb/configuration.rb +++ b/lib/bb/configuration.rb @@ -11,11 +11,11 @@ module BB # Configuration class used to setup the environment used by client class Configuration < Common::Client::Configuration::REST def app_token - ENV['MHV_APP_TOKEN'] + Settings.mhv.rx.app_token end def base_path - "#{ENV['MHV_HOST']}/mhv-api/patient/v1/" + "#{Settings.mhv.rx.host}/mhv-api/patient/v1/" end def service_name diff --git a/lib/config_helper.rb b/lib/config_helper.rb index 91021f14b6b..d5811a1f687 100644 --- a/lib/config_helper.rb +++ b/lib/config_helper.rb @@ -8,8 +8,8 @@ def setup_action_mailer(config) if FeatureFlipper.send_email? config.action_mailer.delivery_method = :govdelivery_tms config.action_mailer.govdelivery_tms_settings = { - auth_token: ENV['GOV_DELIVERY_TOKEN'], - api_root: "https://#{ENV['GOV_DELIVERY_SERVER']}" + auth_token: Settings.reports.token, + api_root: "https://#{Settings.reports.server}" } end end diff --git a/lib/evss/base_service.rb b/lib/evss/base_service.rb index 601e8ee12af..863002017c8 100644 --- a/lib/evss/base_service.rb +++ b/lib/evss/base_service.rb @@ -68,22 +68,23 @@ def ssl_options end def cert? - ENV['EVSS_CERT_FILE_PATH'].present? || - ENV['EVSS_CERT_KEY_PATH'].present? || - ENV['EVSS_ROOT_CERT_FILE_PATH'].present? + # TODO(knkski): Is this logic correct? + Settings.evss.cert_path.present? || + Settings.evss.key_path.present? || + Settings.evss.root_cert_path.present? end # :nocov: def client_cert - OpenSSL::X509::Certificate.new File.read(ENV['EVSS_CERT_FILE_PATH']) + OpenSSL::X509::Certificate.new File.read(Settings.evss.cert_path) end def client_key - OpenSSL::PKey::RSA.new File.read(ENV['EVSS_CERT_KEY_PATH']) + OpenSSL::PKey::RSA.new File.read(Settings.evss.key_path) end def root_ca - ENV['EVSS_ROOT_CERT_FILE_PATH'] + Settings.evss.root_cert_path end # :nocov: end diff --git a/lib/evss/claims_service.rb b/lib/evss/claims_service.rb index aec3b47acb2..6c20b55b2c2 100644 --- a/lib/evss/claims_service.rb +++ b/lib/evss/claims_service.rb @@ -3,7 +3,7 @@ module EVSS class ClaimsService < BaseService - BASE_URL = "#{ENV['EVSS_BASE_URL']}/wss-claims-services-web-3.0/rest" + BASE_URL = "#{Settings.evss.url}/wss-claims-services-web-3.0/rest" def all_claims get 'vbaClaimStatusService/getClaims' diff --git a/lib/evss/common_service.rb b/lib/evss/common_service.rb index ddfd6f2d688..6d33bd2f222 100644 --- a/lib/evss/common_service.rb +++ b/lib/evss/common_service.rb @@ -3,7 +3,7 @@ module EVSS class CommonService < BaseService - BASE_URL = "#{ENV['EVSS_BASE_URL']}/wss-common-services-web-11.0/rest/" + BASE_URL = "#{Settings.evss.url}/wss-common-services-web-11.0/rest/" def find_rating_info(participant_id) post 'ratingInfoService/11.0/findRatingInfoPID', diff --git a/lib/evss/documents_service.rb b/lib/evss/documents_service.rb index ab110262de2..b2cb2e183a5 100644 --- a/lib/evss/documents_service.rb +++ b/lib/evss/documents_service.rb @@ -3,7 +3,7 @@ module EVSS class DocumentsService < BaseService - BASE_URL = "#{ENV['EVSS_BASE_URL']}/wss-document-services-web-3.0/rest/" + BASE_URL = "#{Settings.evss.url}/wss-document-services-web-3.0/rest/" # this service is only used from an async worker so long timeout is acceptable here DEFAULT_TIMEOUT = 180 # seconds diff --git a/lib/feature_flipper.rb b/lib/feature_flipper.rb index be7e9f6a7ac..5756ba08922 100644 --- a/lib/feature_flipper.rb +++ b/lib/feature_flipper.rb @@ -1,15 +1,15 @@ # frozen_string_literal: true module FeatureFlipper def self.show_education_benefit_form? - # Visible in all situations except in production where EDU_FORM_SHOW is not true - !(Rails.env.production? && ENV['EDU_FORM_SHOW']&.downcase != 'true') + # Visible in all situations except in production where Settings.edu.show_form is not true + !(Rails.env.production? && Settings.edu.show_form) end def self.send_email? - ENV['GOV_DELIVERY_TOKEN'].present? || Rails.env.test? + Settings.reports.token.present? || Rails.env.test? end def self.staging_email? - ENV['GOV_DELIVERY_SERVER'].include?('stage') + Settings.reports.server.include?('stage') end end diff --git a/lib/gi/configuration.rb b/lib/gi/configuration.rb index 20cf4357551..4c5bf6be6f5 100644 --- a/lib/gi/configuration.rb +++ b/lib/gi/configuration.rb @@ -8,7 +8,7 @@ module GI # Configuration class used to setup the environment used by client class Configuration < Common::Client::Configuration::REST def base_path - "#{ENV['GIDS_URL']}/v0/" + "#{Settings.gids.url}/v0/" end def service_name diff --git a/lib/hca/configuration.rb b/lib/hca/configuration.rb index 2b7de13d7c2..b207a60c856 100644 --- a/lib/hca/configuration.rb +++ b/lib/hca/configuration.rb @@ -5,8 +5,6 @@ module HCA class Configuration < Common::Client::Configuration::SOAP - CONFIG = Rails.application.config_for(:health_care_application).freeze - def self.cert_store(paths) store = OpenSSL::X509::Store.new Array(paths).each do |path| @@ -17,10 +15,10 @@ def self.cert_store(paths) HEALTH_CHECK_ID = 377_609_264 WSDL = Rails.root.join('config', 'health_care_application', 'wsdl', 'voa.wsdl') - CERT_STORE = (cert_store(CONFIG['ca']) if CONFIG['ca']) + CERT_STORE = cert_store(Settings.hca.ca) SSL_CERT = begin - OpenSSL::X509::Certificate.new(File.read(ENV['ES_CLIENT_CERT_PATH'])) + OpenSSL::X509::Certificate.new(File.read(Settings.hca.cert_path)) rescue => e # :nocov: Rails.logger.warn "Could not load ES SSL cert: #{e.message}" @@ -30,7 +28,7 @@ def self.cert_store(paths) end SSL_KEY = begin - OpenSSL::PKey::RSA.new(File.read(ENV['ES_CLIENT_KEY_PATH'])) + OpenSSL::PKey::RSA.new(File.read(Settings.hca.key_path)) rescue => e # :nocov: Rails.logger.warn "Could not load ES SSL key: #{e.message}" @@ -40,7 +38,7 @@ def self.cert_store(paths) end def base_path - CONFIG['endpoint'] + Settings.hca.endpoint end def service_name diff --git a/lib/mvi/configuration.rb b/lib/mvi/configuration.rb index e4f40df200e..2cd85be1145 100644 --- a/lib/mvi/configuration.rb +++ b/lib/mvi/configuration.rb @@ -5,22 +5,22 @@ module MVI class Configuration < Common::Client::Configuration::SOAP # :nocov: def self.default_mvi_open_timeout - Rails.logger.warn 'MVI_OPEN_TIMEOUT env variable not set, using default' + Rails.logger.warn 'Settings.mvi.open_timeout not set, using default' 2 end def self.default_mvi_timeout - Rails.logger.warn 'MVI_TIMEOUT env variable not set, using default' + Rails.logger.warn 'Settings.mvi.timeout not set, using default' 10 end # :nocov: - URL = ENV['MVI_URL'] - OPEN_TIMEOUT = ENV['MVI_OPEN_TIMEOUT']&.to_i || default_mvi_open_timeout - TIMEOUT = ENV['MVI_TIMEOUT']&.to_i || default_mvi_timeout + URL = Settings.mvi.url + OPEN_TIMEOUT = Settings.mvi.open_timeout&.to_i || default_mvi_open_timeout + TIMEOUT = Settings.mvi.timeout&.to_i || default_mvi_timeout SSL_CERT = begin - OpenSSL::X509::Certificate.new(File.read(ENV['MVI_CLIENT_CERT_PATH'])) + OpenSSL::X509::Certificate.new(File.read(Settings.mvi.client_cert_path)) rescue => e # :nocov: Rails.logger.warn "Could not load MVI SSL cert: #{e.message}" @@ -30,7 +30,7 @@ def self.default_mvi_timeout end SSL_KEY = begin - OpenSSL::PKey::RSA.new(File.read(ENV['MVI_CLIENT_KEY_PATH'])) + OpenSSL::PKey::RSA.new(File.read(Settings.mvi.client_key_path)) rescue => e # :nocov: Rails.logger.warn "Could not load MVI SSL key: #{e.message}" @@ -40,7 +40,7 @@ def self.default_mvi_timeout end def base_path - ENV['MVI_URL'] + Settings.mvi.url end def service_name diff --git a/lib/mvi/messages/message_builder.rb b/lib/mvi/messages/message_builder.rb index 0591c35672a..02e6ce27e46 100644 --- a/lib/mvi/messages/message_builder.rb +++ b/lib/mvi/messages/message_builder.rb @@ -79,7 +79,7 @@ def build_envelope private def processing_code - ENV['MVI_PROCESSING_CODE'] + Settings.mvi.processing_code end end class MessageBuilderError < StandardError diff --git a/lib/rx/configuration.rb b/lib/rx/configuration.rb index 3f9c18fd39b..c2dd2a890f6 100644 --- a/lib/rx/configuration.rb +++ b/lib/rx/configuration.rb @@ -10,11 +10,11 @@ module Rx # Configuration class used to setup the environment used by client class Configuration < Common::Client::Configuration::REST def app_token - ENV['MHV_APP_TOKEN'] + Settings.mhv.rx.app_token end def base_path - "#{ENV['MHV_HOST']}/mhv-api/patient/v1/" + "#{Settings.mhv.rx.host}/mhv-api/patient/v1/" end def service_name diff --git a/lib/saml/settings_service.rb b/lib/saml/settings_service.rb index cc0463ad64d..957a59e98f0 100644 --- a/lib/saml/settings_service.rb +++ b/lib/saml/settings_service.rb @@ -24,7 +24,7 @@ def saml_settings private def connection - Faraday.new(SAML_CONFIG['metadata_url']) do |conn| + Faraday.new(Settings.saml.metadata_url) do |conn| conn.options.open_timeout = OPEN_TIMEOUT conn.options.timeout = TIMEOUT conn.adapter :net_http @@ -50,10 +50,10 @@ def metadata def settings settings = OneLogin::RubySaml::Settings.new - settings.certificate = SAML_CONFIG['certificate'] - settings.private_key = SAML_CONFIG['key'] - settings.issuer = SAML_CONFIG['issuer'] - settings.assertion_consumer_service_url = SAML_CONFIG['callback_url'] + settings.certificate = Settings.saml.certificate + settings.private_key = Settings.saml.key + settings.issuer = Settings.saml.issuer + settings.assertion_consumer_service_url = Settings.saml.callback_url settings.security[:authn_requests_signed] = true settings.security[:logout_requests_signed] = true diff --git a/lib/sm/configuration.rb b/lib/sm/configuration.rb index 8a3d2706ca6..0b364869e9f 100644 --- a/lib/sm/configuration.rb +++ b/lib/sm/configuration.rb @@ -11,11 +11,11 @@ module SM class Configuration < Common::Client::Configuration::REST def app_token - ENV['MHV_SM_APP_TOKEN'] + Settings.mhv.sm.app_token end def base_path - "#{ENV['MHV_SM_HOST']}/mhv-sm-api/patient/v1/" + "#{Settings.mhv.sm.host}/mhv-sm-api/patient/v1/" end def service_name diff --git a/spec/controllers/v0/sessions_controller_spec.rb b/spec/controllers/v0/sessions_controller_spec.rb index 437a2f613a9..702c4f104b7 100644 --- a/spec/controllers/v0/sessions_controller_spec.rb +++ b/spec/controllers/v0/sessions_controller_spec.rb @@ -58,7 +58,7 @@ it 'responds with error when logout request is not found' do expect(Rails.logger).to receive(:error).exactly(1).times expect(post(:saml_logout_callback, SAMLResponse: '-')) - .to redirect_to(SAML_CONFIG['logout_relay'] + '?success=false') + .to redirect_to(Settings.saml.logout_relay + '?success=false') end context ' logout has been requested' do before { SingleLogoutRequest.create(uuid: logout_uuid, token: token) } @@ -69,7 +69,7 @@ it 'redirects to error' do expect(Rails.logger).to receive(:error).with(/bad thing/).exactly(1).times expect(post(:saml_logout_callback, SAMLResponse: '-')) - .to redirect_to(SAML_CONFIG['logout_relay'] + '?success=false') + .to redirect_to(Settings.saml.logout_relay + '?success=false') end end context ' logout_response is success' do @@ -80,7 +80,7 @@ expect(Session.find(token)).to_not be_nil expect(User.find(uuid)).to_not be_nil expect(post(:saml_logout_callback, SAMLResponse: '-')) - .to redirect_to(redirect_to(SAML_CONFIG['logout_relay'] + '?success=true')) + .to redirect_to(redirect_to(Settings.saml.logout_relay + '?success=true')) expect(Session.find(token)).to be_nil expect(User.find(uuid)).to be_nil end @@ -101,7 +101,7 @@ before { allow(OneLogin::RubySaml::Response).to receive(:new).and_return(saml_response_click_deny) } it 'redirects to an auth failure page' do expect(Rails.logger).to receive(:warn).with(/#{SAML::AuthFailHandler::CLICKED_DENY_MSG}/) - expect(post(:saml_callback)).to redirect_to(SAML_CONFIG['relay'] + '?auth=fail') + expect(post(:saml_callback)).to redirect_to(Settings.saml.relay + '?auth=fail') expect(response).to have_http_status(:found) end end @@ -109,7 +109,7 @@ before { allow(OneLogin::RubySaml::Response).to receive(:new).and_return(saml_response_too_late) } it 'redirects to an auth failure page' do expect(Rails.logger).to receive(:warn).with(/#{SAML::AuthFailHandler::TOO_LATE_MSG}/) - expect(post(:saml_callback)).to redirect_to(SAML_CONFIG['relay'] + '?auth=fail') + expect(post(:saml_callback)).to redirect_to(Settings.saml.relay + '?auth=fail') expect(response).to have_http_status(:found) end end @@ -117,7 +117,7 @@ before { allow(OneLogin::RubySaml::Response).to receive(:new).and_return(saml_response_too_early) } it 'redirects to an auth failure page' do expect(Rails.logger).to receive(:error).with(/#{SAML::AuthFailHandler::TOO_EARLY_MSG}/) - expect(post(:saml_callback)).to redirect_to(SAML_CONFIG['relay'] + '?auth=fail') + expect(post(:saml_callback)).to redirect_to(Settings.saml.relay + '?auth=fail') expect(response).to have_http_status(:found) end end @@ -125,7 +125,7 @@ before { allow(User).to receive(:from_saml).and_return(invalid_user) } it 'logs a generic error' do expect(Rails.logger).to receive(:error).with(/user: \'valid\?=false errors=\["Uuid can\'t be blank"\]/) - expect(post(:saml_callback)).to redirect_to(SAML_CONFIG['relay'] + '?auth=fail') + expect(post(:saml_callback)).to redirect_to(Settings.saml.relay + '?auth=fail') expect(response).to have_http_status(:found) end end diff --git a/spec/factories/configurations.rb b/spec/factories/configurations.rb index dc54825061e..b6181c210d0 100644 --- a/spec/factories/configurations.rb +++ b/spec/factories/configurations.rb @@ -3,7 +3,7 @@ FactoryGirl.define do factory :configuration, class: SM::Configuration do - host ENV['MHV_SM_HOST'] - app_token ENV['MHV_SM_APP_TOKEN'] + host Settings.mhv.sm.host + app_token Settings.mhv.sm.app_token end end diff --git a/spec/factories/rubysaml_settings.rb b/spec/factories/rubysaml_settings.rb index d29b16dcb95..6ae1962f155 100644 --- a/spec/factories/rubysaml_settings.rb +++ b/spec/factories/rubysaml_settings.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true FactoryGirl.define do factory :rubysaml_settings, class: 'OneLogin::RubySaml::Settings' do - certificate SAML_CONFIG['certificate'] - private_key SAML_CONFIG['key'] - issuer SAML_CONFIG['issuer'] - assertion_consumer_service_url SAML_CONFIG['callback_url'] + certificate Settings.saml.certificate + private_key Settings.saml.key + issuer Settings.saml.issuer + assertion_consumer_service_url Settings.saml.callback_url authn_context LOA::MAPPING.invert[1] idp_cert File.read("#{::Rails.root}/spec/fixtures/files/idme_cert.crt") idp_cert_fingerprint '74:DC:33:BE:D6:92:69:3F:81:65:F6:CF:ED:55:82:E0:A5:65:B3:32' @@ -15,10 +15,10 @@ end factory :settings_no_context, class: 'OneLogin::RubySaml::Settings' do - certificate SAML_CONFIG['certificate'] - private_key SAML_CONFIG['key'] - issuer SAML_CONFIG['issuer'] - assertion_consumer_service_url SAML_CONFIG['callback_url'] + certificate Settings.saml.certificate + private_key Settings.saml.key + issuer Settings.saml.issuer + assertion_consumer_service_url Settings.saml.callback_url idp_cert File.read("#{::Rails.root}/spec/fixtures/files/idme_cert.crt") idp_cert_fingerprint '74:DC:33:BE:D6:92:69:3F:81:65:F6:CF:ED:55:82:E0:A5:65:B3:32' idp_entity_id 'api.idmelabs.com' diff --git a/spec/jobs/education_form/create_daily_spool_files_spec.rb b/spec/jobs/education_form/create_daily_spool_files_spec.rb index 050c701a85f..46edaa71688 100644 --- a/spec/jobs/education_form/create_daily_spool_files_spec.rb +++ b/spec/jobs/education_form/create_daily_spool_files_spec.rb @@ -156,7 +156,8 @@ it 'writes files out over sftp' do expect(EducationBenefitsClaim.unprocessed).not_to be_empty - ClimateControl.modify EDU_SFTP_HOST: 'localhost', EDU_SFTP_PASS: 'test' do + + with_settings(Settings.edu.sftp, {host: 'localhost', pass: 'test'}) do sftp_session_mock = instance_double('Net::SSH::Connection::Session') sftp_mock = instance_double('Net::SFTP::Session', session: sftp_session_mock) diff --git a/spec/jobs/education_form/writer/factory_spec.rb b/spec/jobs/education_form/writer/factory_spec.rb index 2b13ab0bde7..7836944cc1e 100644 --- a/spec/jobs/education_form/writer/factory_spec.rb +++ b/spec/jobs/education_form/writer/factory_spec.rb @@ -1,13 +1,13 @@ - - # frozen_string_literal: true + RSpec.describe EducationForm::Writer::Factory, type: :model, form: :education_benefits do subject { described_class } it 'raises an error if in production but lacking auth keys' do expect(Rails.env).to receive('development?').once { false } - ClimateControl.modify EDU_SFTP_HOST: 'localhost', EDU_SFTP_PASS: nil do - expect { subject.get_writer }.to raise_error(Exception, /EDU_SFTP_PASS not set/) + + with_settings(Settings.edu.sftp, {host: 'localhost', pass: nil}) do + expect { subject.get_writer }.to raise_error(Exception, /Settings.edu.sftp.pass not set/) end end @@ -18,7 +18,8 @@ it 'writes to production when possible' do expect(Rails.env).to receive('development?').once { false } - ClimateControl.modify EDU_SFTP_HOST: 'localhost', EDU_SFTP_PASS: 'test' do + + with_settings(Settings.edu.sftp, {host: 'localhost', pass: 'test'}) do expect(subject.get_writer).to be(EducationForm::Writer::Remote) end end diff --git a/spec/lib/mvi/configuration_spec.rb b/spec/lib/mvi/configuration_spec.rb index 5973b715d00..1ccaeb3c69e 100644 --- a/spec/lib/mvi/configuration_spec.rb +++ b/spec/lib/mvi/configuration_spec.rb @@ -33,21 +33,20 @@ end end end + + # TODO(knkski): These tests probably aren't doing anything useful. describe '.default_mvi_open_timeout' do - context 'when MVI_OPEN_TIMEOUT is not set' do - it 'should use the defaul' do - ClimateControl.modify MVI_OPEN_TIMEOUT: nil do - expect(MVI::Configuration::OPEN_TIMEOUT).to eq(2) - end + context 'when Settings.mvi.open_timeout is not set' do + it 'should use the default' do + expect(MVI::Configuration::OPEN_TIMEOUT).to eq(2) end end end + describe '.default_mvi_timeout' do - context 'when MVI_TIMEOUT is not set' do + context 'when Settings.mvi.timeout is not set' do it 'should use the default' do - ClimateControl.modify MVI_TIMEOUT: nil do - expect(MVI::Configuration::TIMEOUT).to eq(10) - end + expect(MVI::Configuration::TIMEOUT).to eq(10) end end end diff --git a/spec/lib/mvi/messages/message_builder_spec.rb b/spec/lib/mvi/messages/message_builder_spec.rb index d4ba950fd3a..9ce7172e441 100644 --- a/spec/lib/mvi/messages/message_builder_spec.rb +++ b/spec/lib/mvi/messages/message_builder_spec.rb @@ -46,16 +46,16 @@ end describe 'processing code node' do - context 'in non production environments' do + context 'in non-production environments' do it 'has a processing code node of T' do - ClimateControl.modify MVI_PROCESSING_CODE: 'T' do + with_settings(Settings.mvi, {processing_code: 'T'}) do expect(message.locate('processingCode').first.attributes).to eq(code: 'T') end end end context 'in production environments' do it 'has a processing code node of P' do - ClimateControl.modify MVI_PROCESSING_CODE: 'P' do + with_settings(Settings.mvi, {processing_code: 'P'}) do expect(message.locate('processingCode').first.attributes).to eq(code: 'P') end end diff --git a/spec/lib/mvi/service_factory_spec.rb b/spec/lib/mvi/service_factory_spec.rb index 4acf6ef3cc0..42ceaf03ca1 100644 --- a/spec/lib/mvi/service_factory_spec.rb +++ b/spec/lib/mvi/service_factory_spec.rb @@ -2,43 +2,21 @@ require 'mvi/service_factory' describe MVI::ServiceFactory do - context 'when used without an env var' do - context 'when mock_service is false' do - it 'should return the real service' do - expect(MVI::ServiceFactory.get_service(mock_service: false)).to be_an_instance_of(MVI::Service) - end - end - context 'when mock_service is true' do - it 'should return the mock service' do - expect(MVI::ServiceFactory.get_service(mock_service: true)).to be_an_instance_of(MVI::MockService) - end + context 'when mock_service is false' do + it 'should return the real service' do + expect(MVI::ServiceFactory.get_service(mock_service: false)).to be_an_instance_of(MVI::Service) end end - context 'when used with an env var' do - context 'when MOCK_MVI_SERVICE is false' do - it 'should return the real service' do - ClimateControl.modify MOCK_MVI_SERVICE: 'false' do - expect( - MVI::ServiceFactory.get_service(mock_service: ENV['MOCK_MVI_SERVICE']) - ).to be_an_instance_of(MVI::Service) - end - end - end - context 'when MOCK_MVI_SERVICE is nil' do - it 'should return the real service' do - ClimateControl.modify MOCK_MVI_SERVICE: nil do - expect(MVI::ServiceFactory.get_service).to be_an_instance_of(MVI::Service) - end - end + + context 'when mock_service is true' do + it 'should return the mock service' do + expect(MVI::ServiceFactory.get_service(mock_service: true)).to be_an_instance_of(MVI::MockService) end - context 'when MOCK_MVI_SERVICE is true' do - it 'should return the mock service' do - ClimateControl.modify MOCK_MVI_SERVICE: 'true' do - expect( - MVI::ServiceFactory.get_service(mock_service: ENV['MOCK_MVI_SERVICE']) - ).to be_an_instance_of(MVI::MockService) - end - end + end + + context 'when Settings.mvi.mock is nil' do + it 'should return the real service' do + expect(MVI::ServiceFactory.get_service).to be_an_instance_of(MVI::Service) end end end diff --git a/spec/lib/saml/saml_settings_service_spec.rb b/spec/lib/saml/saml_settings_service_spec.rb index 1deb4603dff..bdbfb052687 100644 --- a/spec/lib/saml/saml_settings_service_spec.rb +++ b/spec/lib/saml/saml_settings_service_spec.rb @@ -6,11 +6,11 @@ describe '.saml_settings' do context 'with a 200 response' do it 'should only ever make 1 external web call' do - stub_request(:get, SAML_CONFIG['metadata_url']).to_return(status: 200, body: 'abc') + stub_request(:get, Settings.saml.metadata_url).to_return(status: 200, body: 'abc') SAML::SettingsService.saml_settings SAML::SettingsService.saml_settings SAML::SettingsService.saml_settings - expect(a_request(:get, SAML_CONFIG['metadata_url'])).to have_been_made.at_most_once + expect(a_request(:get, Settings.saml.metadata_url)).to have_been_made.at_most_once end it 'returns a settings instance' do expect(SAML::SettingsService.saml_settings(true)).to be_an_instance_of(OneLogin::RubySaml::Settings) @@ -18,7 +18,7 @@ end context 'with metadata 500 responses' do it 'should log three attempts' do - stub_request(:get, SAML_CONFIG['metadata_url']).to_return( + stub_request(:get, Settings.saml.metadata_url).to_return( status: 500, body: 'bad news bears' ) expect(Rails.logger).to receive(:warn).exactly(2).times.with(/Failed to load SAML metadata: 500: try \d of 3/) @@ -28,7 +28,7 @@ end context 'when a parsing error occurs' do it 'should log and reraise the error' do - stub_request(:get, SAML_CONFIG['metadata_url']).to_return(status: 200, body: '') { ENV['MHV_SM_HOST'] } - c.filter_sensitive_data('') { ENV['MHV_SM_APP_TOKEN'] } - c.filter_sensitive_data('') { ENV['MHV_HOST'] } - c.filter_sensitive_data('') { ENV['GIDS_URL'] } - c.filter_sensitive_data('') { ENV['MHV_APP_TOKEN'] } - c.filter_sensitive_data('') { ENV['MVI_URL'] } - c.filter_sensitive_data('') { ENV['EVSS_BASE_URL'] } + c.filter_sensitive_data('') { Settings.mhv.rx.app_token } + c.filter_sensitive_data('') { Settings.evss.url } + c.filter_sensitive_data('') { Settings.gids.url } + c.filter_sensitive_data('') { Settings.mhv.rx.host } + c.filter_sensitive_data('') { Settings.mhv.sm.app_token } + c.filter_sensitive_data('') { Settings.mhv.sm.host } + c.filter_sensitive_data('') { Settings.mvi.url } c.before_record do |i| %i(response request).each do |env| next unless i.send(env).headers.keys.include?('Token') diff --git a/spec/request/saml_metadata_spec.rb b/spec/request/saml_metadata_spec.rb index a8739108724..d8c4381099b 100644 --- a/spec/request/saml_metadata_spec.rb +++ b/spec/request/saml_metadata_spec.rb @@ -14,6 +14,6 @@ xml = Nokogiri::XML(response.body) entity_id = xml.at_xpath('//md:EntityDescriptor/@entityID', 'md' => 'urn:oasis:names:tc:SAML:2.0:metadata') - expect(entity_id.value).to eq(SAML_CONFIG['issuer']) + expect(entity_id.value).to eq(Settings.saml.issuer) end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 5c3b73dcc7b..cdd6fe3d794 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -13,12 +13,12 @@ add_filter 'config/initializers/sidekiq.rb' add_filter 'config/initializers/statsd.rb' add_filter 'config/initializers/mvi_settings.rb' + add_filter 'config/initializers/config.rb' add_filter 'lib/tasks/support/shell_command.rb' add_filter 'lib/config_helper.rb' add_filter 'lib/feature_flipper.rb' add_filter 'spec/support/authenticated_session_helper' add_filter 'spec/support/attr_encrypted_matcher' - add_filter 'config/initializers/figaro.rb' SimpleCov.minimum_coverage_by_file 90 end end diff --git a/spec/support/aws_helpers.rb b/spec/support/aws_helpers.rb index 057647a4c5c..d1c0ff7650a 100644 --- a/spec/support/aws_helpers.rb +++ b/spec/support/aws_helpers.rb @@ -1,33 +1,25 @@ # frozen_string_literal: true module AwsHelpers - # rubocop:disable Metrics/MethodLength def stub_reports_s3(filename) url = 'http://foo' - ClimateControl.modify( - REPORTS_AWS_S3_REGION: 'region', - REPORTS_AWS_ACCESS_KEY_ID: 'key', - REPORTS_AWS_SECRET_ACCESS_KEY: 'secret', - REPORTS_AWS_S3_BUCKET: 'bucket' - ) do - s3 = double - uuid = 'foo' - bucket = double - obj = double + s3 = double + uuid = 'foo' + bucket = double + obj = double - expect(Aws::S3::Resource).to receive(:new).once.with( - region: 'region', - access_key_id: 'key', - secret_access_key: 'secret' - ).and_return(s3) - expect(SecureRandom).to receive(:uuid).once.and_return(uuid) - expect(s3).to receive(:bucket).once.with('bucket').and_return(bucket) - expect(bucket).to receive(:object).once.with("#{uuid}.csv").and_return(obj) - expect(obj).to receive(:upload_file).once.with(filename, content_type: 'text/csv') - expect(obj).to receive(:presigned_url).once.with(:get, expires_in: 1.week).and_return(url) + expect(Aws::S3::Resource).to receive(:new).once.with( + region: 'region', + access_key_id: 'key', + secret_access_key: 'secret' + ).and_return(s3) + expect(SecureRandom).to receive(:uuid).once.and_return(uuid) + expect(s3).to receive(:bucket).once.with('bucket').and_return(bucket) + expect(bucket).to receive(:object).once.with("#{uuid}.csv").and_return(obj) + expect(obj).to receive(:upload_file).once.with(filename, content_type: 'text/csv') + expect(obj).to receive(:presigned_url).once.with(:get, expires_in: 1.week).and_return(url) - yield - end + yield url end diff --git a/spec/support/rx_client_helpers.rb b/spec/support/rx_client_helpers.rb index d174dbd8572..30dc06e007b 100644 --- a/spec/support/rx_client_helpers.rb +++ b/spec/support/rx_client_helpers.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Rx module ClientHelpers - HOST = ENV['MHV_HOST'] + HOST = Settings.mhv.rx.host CONTENT_TYPE = 'application/json' APP_TOKEN = 'your-unique-app-token' TOKEN = 'GkuX2OZ4dCE=48xrH6ObGXZ45ZAg70LBahi7CjswZe8SZGKMUVFIU88=' diff --git a/spec/uploaders/disability_claim_document_uploader_spec.rb b/spec/uploaders/disability_claim_document_uploader_spec.rb index 7ad845cb8a2..b81045892d6 100644 --- a/spec/uploaders/disability_claim_document_uploader_spec.rb +++ b/spec/uploaders/disability_claim_document_uploader_spec.rb @@ -5,28 +5,24 @@ subject { described_class.new('1234', '11') } describe 'initialize' do - context 'when EVSS_S3_UPLOADS is "false"' do + context 'when uploads are disabled' do it 'should set storage to file' do - ClimateControl.modify(EVSS_S3_UPLOADS: 'false') do + + with_settings(Settings.evss.s3, {uploads_enabled: false}) do expect(subject.class.storage).to eq(CarrierWave::Storage::File) end end end - context 'when EVSS_S3_UPLOADS is nil' do + context 'when uploads are set to nil' do it 'should set storage to file' do - ClimateControl.modify(EVSS_S3_UPLOADS: nil) do + with_settings(Settings.evss.s3, {uploads_enabled: nil}) do expect(subject.class.storage).to eq(CarrierWave::Storage::File) end end end - context 'when EVSS_S3_UPLOADS is "true"' do + context 'when uploads are enabled' do it 'should set storage to fog' do - env_vars = { - EVSS_S3_UPLOADS: 'true', - EVSS_AWS_S3_BUCKET: 'evss_s3_bucket', - EVSS_AWS_S3_REGION: 'evss_s3_region' - } - ClimateControl.modify(env_vars) do + with_settings(Settings.evss.s3, {uploads_enabled: true}) do expect(subject.class.storage).to eq(CarrierWave::Storage::AWS) expect(subject.aws_credentials).to eq(region: 'evss_s3_region') expect(subject.aws_acl).to eq('private') diff --git a/spec/uploaders/evss_claim_document_uploader_spec.rb b/spec/uploaders/evss_claim_document_uploader_spec.rb index f560c9a7497..b2ed9813e8b 100644 --- a/spec/uploaders/evss_claim_document_uploader_spec.rb +++ b/spec/uploaders/evss_claim_document_uploader_spec.rb @@ -5,28 +5,23 @@ subject { described_class.new('1234', '11') } describe 'initialize' do - context 'when EVSS_S3_UPLOADS is "false"' do + context 'when uploads are disabled' do it 'should set storage to file' do - ClimateControl.modify(EVSS_S3_UPLOADS: 'false') do + with_settings(Settings.evss.s3, {uploads_enabled: false}) do expect(subject.class.storage).to eq(CarrierWave::Storage::File) end end end - context 'when EVSS_S3_UPLOADS is nil' do + context 'when uploads are set to nil' do it 'should set storage to file' do - ClimateControl.modify(EVSS_S3_UPLOADS: nil) do + with_settings(Settings.evss.s3, {uploads_enabled: nil}) do expect(subject.class.storage).to eq(CarrierWave::Storage::File) end end end - context 'when EVSS_S3_UPLOADS is "true"' do + context 'when uploads are enabled' do it 'should set storage to fog' do - env_vars = { - EVSS_S3_UPLOADS: 'true', - EVSS_AWS_S3_BUCKET: 'evss_s3_bucket', - EVSS_AWS_S3_REGION: 'evss_s3_region' - } - ClimateControl.modify(env_vars) do + with_settings(Settings.evss.s3, {uploads_enabled: true}) do expect(subject.class.storage).to eq(CarrierWave::Storage::AWS) expect(subject.aws_credentials).to eq(region: 'evss_s3_region') expect(subject.aws_acl).to eq('private')