Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a5d9e9c
Add config/initializers/sandbox.rb to disable emails
aaronskiba Dec 10, 2025
9c28f64
Disable SSO if `on_sandbox` feature flag is enabled
aaronskiba Dec 10, 2025
08903a1
Replace `.funder_org_id` with `.default_funder_id`
aaronskiba Jan 2, 2026
bb423a7
Remove `funder_org_id` from secrets and charts/
aaronskiba Jan 5, 2026
dd466e9
Limit num of Orgs in sandbox seed data & refactor
aaronskiba Jan 2, 2026
c7d885f
Ignore Guidances & GuidanceGroups in sandbox seeds
aaronskiba Jan 3, 2026
11e5e17
Update generation/handling of sandbox templates
aaronskiba Jan 5, 2026
8aa0e0b
Simplify sandbox password handling
aaronskiba Jan 5, 2026
bc28f05
Remove uneeded `test_password` secret
aaronskiba Jan 5, 2026
f2b40db
Refactor/Remove english_org_id & french_org_id secrets
aaronskiba Jan 6, 2026
2f9f25e
Filter Guidances/Groups by default + test orgs
aaronskiba Jan 7, 2026
bd8d0f8
Refactor export_portage.rake
aaronskiba Jan 7, 2026
050d6dd
Fix user.org for superuser in `seeds_4.rb`
aaronskiba Jan 13, 2026
f5ec2b0
Refactor `seeds_4.rb`
aaronskiba Jan 13, 2026
2190e77
Rename db/seeds/sandbox -> db/seeds/production
aaronskiba Jan 12, 2026
e6a4fec
Bugfix in template assignment of sandbox seeds
aaronskiba Jan 13, 2026
a2b9d93
Update num plans & plan.template in seeds
aaronskiba Jan 14, 2026
4d3915c
Enable seed-loading in `db/seeds/production.rb`
aaronskiba Jan 13, 2026
f93bf7d
`rails export_production_data:build_sandbox_data`
aaronskiba Jan 14, 2026
2b5c983
Add guard to prevent seeding non-sandbox overlays
aaronskiba Jan 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions app/controllers/users/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ module Users
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
include EmailConfirmationHandler

before_action :block_openid_connect_in_sandbox, only: [:openid_connect]

# This is for the OpenidConnect CILogon
def openid_connect
auth = request.env['omniauth.auth']
Expand Down Expand Up @@ -110,6 +112,12 @@ def failure

private

def block_openid_connect_in_sandbox
return unless FeatureFlagHelper.enabled?(:on_sandbox)

redirect_to root_path, alert: _('OpenID Connect is not available in sandbox.')
end

def handle_missing_email_for_new_sso_entry
flash[:alert] = generate_flash_message_for_missing_email
# Signed out user stays on 'Sign in' page
Expand Down
22 changes: 12 additions & 10 deletions app/views/devise/registrations/_personal_details.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,18 @@
</div>
</div>

<div class="form-group col-xs-8">
<label class='control-label'>
<span class="aria-only" aria-hidden="false"><%= _('Institutional credentials') %></span>
</label>
<div class='identifier-scheme'>
<%= render partial: 'external_openid_connect',
locals: { scheme: IdentifierScheme.find_by( name: 'openid_connect'),
id: current_user.identifier_for('openid_connect')} %>
</div>
</div>
<% unless FeatureFlagHelper.enabled?(:on_sandbox) %>
<div class="form-group col-xs-8">
<label class='control-label'>
<span class="aria-only" aria-hidden="false"><%= _('Institutional credentials') %></span>
</label>
<div class='identifier-scheme'>
<%= render partial: 'external_openid_connect',
locals: { scheme: IdentifierScheme.find_by( name: 'openid_connect'),
id: current_user.identifier_for('openid_connect')} %>
</div>
</div>
<% end %>


<div class="form-group col-xs-8">
Expand Down
6 changes: 3 additions & 3 deletions app/views/shared/_sign_in_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,16 @@
<% end %>


<% if Rails.configuration.x.openid_connect.enabled %>
<% if session['devise.openid_connect_data'].nil? %>
<% unless FeatureFlagHelper.enabled?(:on_sandbox) %>
<% if Rails.configuration.x.openid_connect.enabled && session['devise.openid_connect_data'].nil? %>
<p class="text-center fontsize-h4">- <%= _('or') %> -</p>
<div class="form-group">
<span class="center-block btn-group-justified">
<%= link_to _("Sign in with institutional or social ID").html_safe, user_openid_connect_omniauth_authorize_path, method: :post, data: { turbo: false }, class: 'btn btn-default' %>
</span>
</div>
<% else %>
<% end %>
<% end %>
<% end %>

<% end %>
12 changes: 0 additions & 12 deletions charts/dmp-roadmap/templates/app/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,6 @@ data:
DEFAULT_FUNDER_ID: {{ .Values.config.environment.defaultFunderId | quote }}
{{- end }}

{{- if .Values.config.environment.funderOrgId }}
FUNDER_ORG_ID: {{ .Values.config.environment.funderOrgId | quote }}
{{- end }}

{{- if .Values.config.environment.frenchOrgId }}
FRENCH_ORG_ID: {{ .Values.config.environment.frenchOrgId | quote }}
{{- end }}

{{- if .Values.config.environment.englishOrgId }}
ENGLISH_ORG_ID: {{ .Values.config.environment.englishOrgId | quote }}
{{- end }}

{{- if .Values.config.environment.orcidClientMember }}
ORCID_CLIENT_MEMBER: {{ .Values.config.environment.orcidClientMember | quote }}
{{- end }}
Expand Down
8 changes: 8 additions & 0 deletions config/initializers/sandbox.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

# All deployed environments use RAILS_ENV=production and config/environments/production.rb.
# Here, we override certain settings based on feature flags (e.g., on_sandbox).

# Prevent actual email delivery in sandbox
# Note: Using secrets directly here to avoid autoloading FeatureFlagHelper during initialization
Rails.application.config.action_mailer.delivery_method = :test if Rails.application.secrets.on_sandbox.to_s == 'true'
42 changes: 0 additions & 42 deletions config/secrets.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,7 @@ test:
wicked_pdf_path: <%= ENV['WICKED_PDF_PATH'] %>
wicked_pdf_proxy: <%= ENV['WICKED_PDF_PROXY'] %>
default_funder_id: <%= ENV['DEFAULT_FUNDER_ID'] %>
super_admin_password: <%= ENV["SUPER_ADMIN_PASSWORD"] %>
test_password: <%= ENV["TEST_PASSWORD"] %>
user_password: <%= ENV["USER_PASSWORD"] %>
english_admin_password: <%= ENV["ENGLISH_ADMIN_PASSWORD"] %>
english_org_id: <%= ENV["ENGLISH_ORG_ID"] %>
french_admin_password: <%= ENV["FRENCH_ADMIN_PASSWORD"] %>
french_org_id: <%= ENV["FRENCH_ORG_ID"] %>
funder_org_id: <%= ENV["FUNDER_ORG_ID"] %>
on_sandbox: <%= ENV["ON_SANDBOX"] %>
cilogon_client_id: <%= ENV["CILOGON_CLIENT_ID"]%>
cilogon_secret_key: <%= ENV["CILOGON_SECRET_KEY"]%>
Expand All @@ -63,14 +56,7 @@ development:
wicked_pdf_path: <%= ENV['WICKED_PDF_PATH'] %>
wicked_pdf_proxy: <%= ENV['WICKED_PDF_PROXY'] %>
default_funder_id: <%= ENV['DEFAULT_FUNDER_ID'] %>
super_admin_password: <%= ENV["SUPER_ADMIN_PASSWORD"] %>
test_password: <%= ENV["TEST_PASSWORD"] %>
user_password: <%= ENV["USER_PASSWORD"] %>
english_admin_password: <%= ENV["ENGLISH_ADMIN_PASSWORD"] %>
english_org_id: <%= ENV["ENGLISH_ORG_ID"] %>
french_admin_password: <%= ENV["FRENCH_ADMIN_PASSWORD"] %>
french_org_id: <%= ENV["FRENCH_ORG_ID"] %>
funder_org_id: <%= ENV["FUNDER_ORG_ID"] %>
on_sandbox: <%= ENV["ON_SANDBOX"] %>
cilogon_client_id: <%= ENV["CILOGON_CLIENT_ID"]%>
cilogon_secret_key: <%= ENV["CILOGON_SECRET_KEY"]%>
Expand Down Expand Up @@ -105,14 +91,7 @@ staging:
wicked_pdf_path: <%= ENV['WICKED_PDF_PATH'] %>
wicked_pdf_proxy: <%= ENV['WICKED_PDF_PROXY'] %>
default_funder_id: <%= ENV['DEFAULT_FUNDER_ID'] %>
super_admin_password: <%= ENV["SUPER_ADMIN_PASSWORD"] %>
test_password: <%= ENV["TEST_PASSWORD"] %>
user_password: <%= ENV["USER_PASSWORD"] %>
english_admin_password: <%= ENV["ENGLISH_ADMIN_PASSWORD"] %>
english_org_id: <%= ENV["ENGLISH_ORG_ID"] %>
french_admin_password: <%= ENV["FRENCH_ADMIN_PASSWORD"] %>
french_org_id: <%= ENV["FRENCH_ORG_ID"] %>
funder_org_id: <%= ENV["FUNDER_ORG_ID"] %>
on_sandbox: <%= ENV["ON_SANDBOX"] %>
cilogon_client_id: <%= ENV["CILOGON_CLIENT_ID"]%>
cilogon_secret_key: <%= ENV["CILOGON_SECRET_KEY"]%>
Expand Down Expand Up @@ -147,14 +126,7 @@ uat:
wicked_pdf_path: <%= ENV['WICKED_PDF_PATH'] %>
wicked_pdf_proxy: <%= ENV['WICKED_PDF_PROXY'] %>
default_funder_id: <%= ENV['DEFAULT_FUNDER_ID'] %>
super_admin_password: <%= ENV["SUPER_ADMIN_PASSWORD"] %>
test_password: <%= ENV["TEST_PASSWORD"] %>
user_password: <%= ENV["USER_PASSWORD"] %>
english_admin_password: <%= ENV["ENGLISH_ADMIN_PASSWORD"] %>
english_org_id: <%= ENV["ENGLISH_ORG_ID"] %>
french_admin_password: <%= ENV["FRENCH_ADMIN_PASSWORD"] %>
french_org_id: <%= ENV["FRENCH_ORG_ID"] %>
funder_org_id: <%= ENV["FUNDER_ORG_ID"] %>
on_sandbox: <%= ENV["ON_SANDBOX"] %>
cilogon_client_id: <%= ENV["CILOGON_CLIENT_ID"]%>
cilogon_secret_key: <%= ENV["CILOGON_SECRET_KEY"]%>
Expand Down Expand Up @@ -189,14 +161,7 @@ sandbox:
wicked_pdf_path: <%= ENV['WICKED_PDF_PATH'] %>
wicked_pdf_proxy: <%= ENV['WICKED_PDF_PROXY'] %>
default_funder_id: <%= ENV['DEFAULT_FUNDER_ID'] %>
super_admin_password: <%= ENV["SUPER_ADMIN_PASSWORD"] %>
test_password: <%= ENV["TEST_PASSWORD"] %>
user_password: <%= ENV["USER_PASSWORD"] %>
english_admin_password: <%= ENV["ENGLISH_ADMIN_PASSWORD"] %>
english_org_id: <%= ENV["ENGLISH_ORG_ID"] %>
french_admin_password: <%= ENV["FRENCH_ADMIN_PASSWORD"] %>
french_org_id: <%= ENV["FRENCH_ORG_ID"] %>
funder_org_id: <%= ENV["FUNDER_ORG_ID"] %>
on_sandbox: <%= ENV["ON_SANDBOX"] %>
cilogon_client_id: <%= ENV["CILOGON_CLIENT_ID"]%>
cilogon_secret_key: <%= ENV["CILOGON_SECRET_KEY"]%>
Expand Down Expand Up @@ -231,14 +196,7 @@ production:
wicked_pdf_path: <%= ENV['WICKED_PDF_PATH'] %>
wicked_pdf_proxy: <%= ENV['WICKED_PDF_PROXY'] %>
default_funder_id: <%= ENV['DEFAULT_FUNDER_ID'] %>
super_admin_password: <%= ENV["SUPER_ADMIN_PASSWORD"] %>
test_password: <%= ENV["TEST_PASSWORD"] %>
user_password: <%= ENV["USER_PASSWORD"] %>
english_admin_password: <%= ENV["ENGLISH_ADMIN_PASSWORD"] %>
english_org_id: <%= ENV["ENGLISH_ORG_ID"] %>
french_admin_password: <%= ENV["FRENCH_ADMIN_PASSWORD"] %>
french_org_id: <%= ENV["FRENCH_ORG_ID"] %>
funder_org_id: <%= ENV["FUNDER_ORG_ID"] %>
on_sandbox: <%= ENV["ON_SANDBOX"] %>
cilogon_client_id: <%= ENV["CILOGON_CLIENT_ID"]%>
cilogon_secret_key: <%= ENV["CILOGON_SECRET_KEY"]%>
37 changes: 21 additions & 16 deletions db/seeds/production.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,32 @@
# frozen_string_literal: true
# warn_indent: true

########## For sandbox only
########## For sandbox overlay only
# Steps:
# 1) change default database to production database, then run `rails export:build_sandbox_data` to generate production-related data
# 2) switch database to the sandbox database
# 3) run rake db:seed or created alongside the db with db:setup to seed data
# 1) Using a db in a desired state, run `rails export_production_data:build_sandbox_data`
# - This will generate new seed data in db/seeds/production/
# - (Note: This step can be completeled locally via a db dump and committing the seed files to git)
# 2) Execute `bin/rails db:setup` against the sandbox overlay (creates the DB and seeds it)
# - Note: the "sandbox" overlay runs with `RAILS_ENV=production`;
# DO NOT execute `bin/rails db:setup` against any non-sandbox overlays!!!
# - Note: This file is only used during step 2
##########
# Forcing load seed file in sequence by last number
# seeds_1 to seeds_3 are rake-generated. Other seeds file are manually edited
########## Uncomment following if we need to redo sandbox data injection
# puts 'run seeds.rb file now...'
# Dir[File.join(Rails.root, 'db', 'seeds', 'sandbox', '*.rb')].sort.each_with_index do |seed, index|
# if seed.include? index.to_s
# load seed
# end
# end

unless FeatureFlagHelper.enabled?(:on_sandbox)
raise <<~ERROR
ERROR: These seeds are for the sandbox overlay only!
The ON_SANDBOX flag is not enabled.
Please verify you are on the sandbox overlay and ON_SANDBOX='true' is set.
Do NOT run db:setup against any non-sandbox overlays!
ERROR
end

######## For 3.1.0 Migration only
Rake::Task['before_seeds:copy_data'].invoke
Dir[File.join(Rails.root, 'db', 'seeds', 'staging', '*.rb')].sort.each_with_index do |seed, index|
puts 'run staging/seeds_' + index.to_s + '.rb now..'
load seed
puts 'run seeds.rb file now...'
Dir[File.join(Rails.root, 'db', 'seeds', 'production', '*.rb')].sort.each_with_index do |seed, index|
if seed.include? index.to_s
load seed
end
end
Rake::Task['rewrite_postgres:retrieve_data'].invoke
File renamed without changes.
10 changes: 10 additions & 0 deletions db/seeds/production/seeds_1.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Org.create!({"id"=>8, "name"=>"Digital Research Alliance of Canada", "abbreviation"=>"Alliance", "target_url"=>"https://portagenetwork.ca/", "is_other"=>false, "display_in_registration"=>true, "logo_uid"=>"2025/04/23/91vtalebl4_Alliance_logo_English_first.png", "logo_name"=>"Alliance_logo_English-first.png", "banner_uid"=>nil, "banner_name"=>nil, "region_id"=>nil, "language_id"=>1, "contact_email"=>"[email protected]", "org_type"=>3, "links"=>{"org"=>[{"link"=>"https://alliancecan.ca/en/services/research-data-management", "text"=>"Digital Research Alliance of Canada"}]}, "contact_name"=>"Support", "feedback_enabled"=>false, "feedback_msg"=>"<p>Hello %{user_name}.</p>\r\n<p>Your plan \"%{plan_name}\" has been submitted for feedback from an administrator at your organisation. If you have questions pertaining to this action, please contact us at %{organisation_email}.</p>", "managed"=>true, "helpdesk_email"=>""})
Org.create!({"id"=>1432, "name"=>"Test Organization", "abbreviation"=>"IEO", "target_url"=>nil, "is_other"=>false, "display_in_registration"=>nil, "logo_uid"=>nil, "logo_name"=>nil, "banner_uid"=>nil, "banner_name"=>nil, "region_id"=>nil, "language_id"=>1, "contact_email"=>"[email protected]", "org_type"=>0, "links"=>{"org"=>[]}, "contact_name"=>"Test User", "feedback_enabled"=>false, "feedback_msg"=>"<p>Hello %{user_name}.</p>\n<br><p>\nYour plan \"%{plan_name}\" has been submitted for feedback from an administrator at your organisation.\n<br>If you have questions pertaining to this action, please contact us at %{organisation_email}.\n</p>\n", "managed"=>false, "helpdesk_email"=>nil})
Org.create!({"id"=>69, "name"=>"Organisation de test", "abbreviation"=>"OEO", "target_url"=>nil, "is_other"=>false, "display_in_registration"=>nil, "logo_uid"=>nil, "logo_name"=>nil, "banner_uid"=>nil, "banner_name"=>nil, "region_id"=>nil, "language_id"=>2, "contact_email"=>"[email protected]", "org_type"=>1, "links"=>{"org"=>[{"link"=>"https://www.organisationdetest.ca", "text"=>"organisationdetest.ca"}]}, "contact_name"=>"Utilisateur test", "feedback_enabled"=>true, "feedback_msg"=>"<p>Bonjour %{user_name}.</p>\n<br><p>Votre plan \"%{plan_name}\" a été soumis pour commentaires d’un administrateur de votre organisation.\n<br>Si vous avez des questions concernant cette action, veuillez communiquer avec nous à %{organisation_email}.\n</p>\n", "managed"=>true, "helpdesk_email"=>nil})
QuestionFormat.create({"id"=>1, "title"=>"Text area", "description"=>"a box that allows input of multiple lines of text", "option_based"=>false, "formattype"=>"textarea"})
QuestionFormat.create({"id"=>2, "title"=>"Text field", "description"=>"a box that allows input of a single line of text", "option_based"=>false, "formattype"=>"textfield"})
QuestionFormat.create({"id"=>3, "title"=>"Radio buttons", "description"=>"a group of buttons that allow selection of a single value out of a set", "option_based"=>true, "formattype"=>"radiobuttons"})
QuestionFormat.create({"id"=>4, "title"=>"Check box", "description"=>"a group of buttons that allow selection of multiple values out of a set", "option_based"=>true, "formattype"=>"checkbox"})
QuestionFormat.create({"id"=>5, "title"=>"Dropdown", "description"=>"an area that displays a list of available values where one can be selected", "option_based"=>true, "formattype"=>"dropdown"})
QuestionFormat.create({"id"=>6, "title"=>"Multi select box", "description"=>"an area that displays a list of available values where multiple can be selected", "option_based"=>true, "formattype"=>"multiselectbox"})
QuestionFormat.create({"id"=>7, "title"=>"Date", "description"=>"a date selection field", "option_based"=>false, "formattype"=>"date"})
8 changes: 8 additions & 0 deletions db/seeds/production/seeds_2.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
GuidanceGroup.create!({"id"=>112, "name"=>"Alliance", "org_id"=>8, "optional_subset"=>false, "published"=>false})
Theme.create!({"id"=>37, "title"=>"Data Collection", "description"=>"This section addresses data collection issues such as data types, file formats, naming conventions, and data organisation – factors that will improve the usability of your data and contribute to the success of your project.", "locale"=>nil})
Theme.create!({"id"=>38, "title"=>"Documentation and Metadata", "description"=>"Because data are rarely self-explanatory, all research data should be accompanied by metadata (information that describes the data according to community best practices). Metadata standards vary across disciplines, but generally state who created the data and when, how the data were created, their quality, accuracy, and precision, as well as other features necessary to facilitate data discovery, understanding and reuse. Any restrictions on use of the data must be explained in the metadata, along with information on how to obtain approved access to the data, where possible.", "locale"=>nil})
Theme.create!({"id"=>39, "title"=>"Storage and Backup", "description"=>"Planning how research data will be stored and backed up throughout and beyond a research project is critical in ensuring data security and integrity. Appropriate storage and backup not only helps protect research data from catastrophic losses (due to hardware and software failures, viruses, hackers, natural disasters, human error, etc.), but also facilitates appropriate access by current and future researchers.", "locale"=>nil})
Theme.create!({"id"=>40, "title"=>"Preservation", "description"=>"Data preservation will depend on potential reuse value, whether there are obligations to either retain or destroy data, and the resources required to properly curate the data and ensure that it remains usable in the future. In some circumstances, it may be desirable to preserve all versions of the data (e.g. raw, processed, analyzed, final), but in others, it may be preferable to keep only selected or final data (e.g. transcripts instead of audio interviews)", "locale"=>nil})
Theme.create!({"id"=>41, "title"=>"Sharing and Reuse", "description"=>"Most Canadian research funding agencies now have policies requiring research data to be shared upon publication of the research results or within a reasonable period of time. While data sharing contributes to the visibility and impact of research, it has to be balanced with the legitimate desire of researchers to maximise their research outputs before releasing their data. Equally important is the need to protect the privacy of respondents and to properly handle sensitive data.", "locale"=>nil})
Theme.create!({"id"=>42, "title"=>"Responsibilities and Resources", "description"=>"Data management focuses on the 'what' and 'how' of operationally supporting data across the research lifecycle. Data stewardship focuses on 'who' is responsible for ensuring that data management happens. A large project, for example, will involve multiple data stewards. The Principal Investigator should identify at the beginning of a project all of the people who will have responsibilities for data management tasks during and after the project.", "locale"=>nil})
Theme.create!({"id"=>43, "title"=>"Ethics and Legal Compliance", "description"=>"Researchers and their teams need to be aware of the policies and processes, both ethical and legal, to which their research data management must comply. Protection of respondent privacy is of paramount importance and informs many data management practices. In their data management plan, researchers must state how they will prepare, store, share, and archive the data in a way that ensures participant information is protected, throughout the research lifecycle, from disclosure, harmful use, or inappropriate linkages with other personal data. It's recognized that there may be cases where certain data and metadata cannot be made public for various policy or legal reasons, however, the default position should be that all research data and metadata are public.", "locale"=>nil})
Loading
Loading