Skip to main content
diff --git a/app/views/layouts/embed.html.erb b/app/views/layouts/embed.html.erb
index 7e4a9dff4a..45d6f4e84f 100644
--- a/app/views/layouts/embed.html.erb
+++ b/app/views/layouts/embed.html.erb
@@ -16,6 +16,7 @@ Unless required by applicable law or agreed to in writing, software distributed
+ <%= render_google_tag_manager_head %>
<%= render_page_title %>
@@ -27,10 +28,10 @@ Unless required by applicable law or agreed to in writing, software distributed
<%= javascript_pack_tag 'embed' %>
<%= yield :page_styles %>
<%= yield :additional_head_content %>
- <%= render "modules/google_analytics" %>
+ <%= render_google_tag_manager_body %>
<%= yield %>
<%= yield :page_scripts %>
diff --git a/app/views/master_files/hls_manifest.m3u8.erb b/app/views/master_files/hls_manifest.m3u8.erb
index 7b2db72b83..2dadfd12c2 100644
--- a/app/views/master_files/hls_manifest.m3u8.erb
+++ b/app/views/master_files/hls_manifest.m3u8.erb
@@ -16,5 +16,5 @@ Unless required by applicable law or agreed to in writing, software distributed
#EXTM3U
<% @hls_streams.each do |hls| %>
#EXT-X-STREAM-INF:BANDWIDTH=<%= hls[:bitrate] %>
-<%= hls[:url] %>
-<% end %>
\ No newline at end of file
+<%= hls[:url].html_safe %>
+<% end %>
diff --git a/bin/boot_container b/bin/boot_container
new file mode 100755
index 0000000000..316714e3af
--- /dev/null
+++ b/bin/boot_container
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+case "$CONTAINER_ROLE" in
+ "migrate")
+ bundle exec rake db:migrate zookeeper:upload zookeeper:create
+ ;;
+ "worker")
+ bundle exec rake shoryuken:create_config
+ exec bundle exec shoryuken --config=config/shoryuken.yml --no-daemon --rails
+ ;;
+ *)
+ exec bundle exec puma -C config/puma_container.rb
+ ;;
+esac
diff --git a/bin/run b/bin/run
new file mode 100755
index 0000000000..a95b54fed7
--- /dev/null
+++ b/bin/run
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+HOME=/home/app
+sudo -u app -E -s $@
diff --git a/config/application.rb b/config/application.rb
index 475af9a286..91ec72058a 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -33,9 +33,27 @@ class Application < Rails::Application
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
- # config.eager_load_paths << Rails.root.join("extras")
- config.active_job.queue_adapter = :sidekiq
+ if Settings&.active_job&.queue_adapter.present?
+ begin
+ require Settings.active_job.queue_adapter.to_s
+ rescue LoadError
+ end
+ config.active_job.queue_adapter = Settings.active_job.queue_adapter.to_s
+ else
+ config.active_job.queue_adapter = :sidekiq
+ end
+
+ config.active_job.queue_name_prefix = Settings&.active_job&.queue_name_prefix
+ config.active_job.queue_name_delimiter = Settings&.active_job&.queue_name_delimiter || (config.active_job.queue_name_prefix.present? ? '-' : nil)
+
+ # ActiveJob::Base gets configured with the queue prefix; ActionMailer::Base without
+ default_queue_name = [
+ config.active_job.queue_name_prefix,
+ Settings&.active_job&.default_queue_name || 'default'
+ ].join(config.active_job.queue_name_delimiter)
+ ActionMailer::Base.deliver_later_queue_name = Settings&.active_job&.default_queue_name || 'default'
+ ActiveJob::Base.queue_name = default_queue_name
config.action_dispatch.default_headers = { 'X-Frame-Options' => 'ALLOWALL' }
@@ -59,6 +77,14 @@ class Application < Rails::Application
config.middleware.insert_before 0, TempfileFactory
+ if Settings&.active_storage&.service_configurations.present?
+ configs = Settings.active_storage.service_configurations.to_hash
+ if config.active_storage.service_configurations.kind_of?(Hash)
+ config.active_storage.service_configurations.merge!(configs)
+ else
+ config.active_storage.service_configurations = configs
+ end
+ end
config.active_storage.service = (Settings&.active_storage&.service.presence || "local").to_sym
end
end
diff --git a/config/database.yml b/config/database.yml
index d2e70a7f1f..f98e569169 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -1,27 +1,22 @@
-# SQLite version 3.x
-# gem install sqlite3
-#
-# Ensure the SQLite 3 gem is defined in your Gemfile
-# gem 'sqlite3'
-#
default: &default
- adapter: sqlite3
- pool: 10
- timeout: 10000
+ adapter: postgresql
+ host: <%= ENV.fetch("DB_HOST") { "localhost" } %>
+ port: <%= ENV.fetch("DB_PORT") { 5432 } %>
+ encoding: unicode
+ pool: 5
+ username: <%= ENV.fetch("DB_USER") { "docker" } %>
+ password: <%= ENV.fetch("DB_PASSWORD") { "d0ck3r" } %>
development:
<<: *default
- database: db/development.sqlite3
+ database: avr-development
-# Warning: The database defined as "test" will be erased and
-# re-generated from your development database when you run "rake".
-# Do not set this db to the same as development or production.
test:
<<: *default
- pool: 20
- database: db/test.sqlite3
+ database: avr-test
production:
- <<: *default
- pool: 20
+ adapter: sqlite3
+ pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
+ timeout: 5000
database: db/production.sqlite3
diff --git a/config/environments/development.rb b/config/environments/development.rb
index 067820227b..5b7e6d305e 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -79,4 +79,11 @@
# Uncomment if you wish to allow Action Cable access from any origin.
# config.action_cable.disable_request_forgery_protection = true
+ if ENV["RAILS_LOG_TO_STDOUT"].present?
+ logger = ActiveSupport::Logger.new(STDOUT)
+ logger.formatter = config.log_formatter
+ config.logger = ActiveSupport::TaggedLogging.new(logger)
+ end
+
+ config.web_console.permissions = '0.0.0.0/0'
end
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 1756dbaf7b..7b2d17ec70 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -56,6 +56,25 @@
# Include generic and useful information about system operation, but avoid logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII).
+ # Use default logging formatter so that PID and timestamp are not suppressed.
+ config.log_formatter = ::Logger::Formatter.new
+
+ # Enable logging to both stdout and file, in more compact format
+ if ENV["RAILS_LOG_TO_STDOUT"].present?
+ logger = ActiveSupport::Logger.new(STDOUT)
+ logger.formatter = config.log_formatter
+ config.logger = ActiveSupport::TaggedLogging.new(logger)
+ end
+
+ if ENV["RAILS_LOG_WITH_LOGRAGE"].present?
+ config.lograge.enabled = true
+ config.lograge.custom_options = -> (event) { { time: event.time } }
+ config.lograge.ignore_actions = ['CatalogController#index']
+ config.lograge.formatter = Lograge::Formatters::Json.new
+ end
+
+ # Use the lowest log level to ensure availability of diagnostic information
+ # when problems arise.
config.log_level = :info
# Suppress logger output for asset requests.
@@ -101,4 +120,7 @@
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
+
+ # Additional production specific initializers
+ Dir["config/environments/production/*.rb"].each {|file| load file }
end
diff --git a/config/initializers/_aws_config.rb b/config/initializers/_aws_config.rb
new file mode 100644
index 0000000000..a2d253b140
--- /dev/null
+++ b/config/initializers/_aws_config.rb
@@ -0,0 +1,42 @@
+if ENV['SSM_PARAM_PATH']
+ require 'aws-sdk-ssm'
+
+ def add_param_to_hash(hash, param, path)
+ remove_segments = path.split(%r{/}).length
+ placement = param.name.split(%r{/})[remove_segments..-1]
+ placement.reject!(&:empty?)
+ key = placement.pop
+ target = hash
+ placement.each { |segment| target = (target[segment] ||= {}) }
+ target[key] = actual_value(param.value)
+ end
+
+ def aws_param_hash(path: '/')
+ result = {}
+ ssm = Aws::SSM::Client.new
+ next_token = nil
+ loop do
+ response = ssm.get_parameters_by_path(path: path, recursive: true, with_decryption: true, next_token: next_token)
+ response.parameters.each do |param|
+ add_param_to_hash(result, param, path)
+ end
+ next_token = response.next_token
+ break if next_token.nil?
+ end
+ result
+ end
+
+ def actual_value(v)
+ case v
+ when 'false'
+ false
+ when 'true'
+ true
+ else
+ Integer(v) rescue Float(v) rescue v
+ end
+ end
+
+ Settings.add_source!(aws_param_hash(path: "#{ENV['SSM_PARAM_PATH']}/Settings"))
+ Settings.reload!
+end
\ No newline at end of file
diff --git a/config/initializers/active_encode.rb b/config/initializers/active_encode.rb
index 1a688a5466..6865d7ce46 100644
--- a/config/initializers/active_encode.rb
+++ b/config/initializers/active_encode.rb
@@ -6,6 +6,10 @@
ActiveEncode::EngineAdapters::FfmpegAdapter.completeness_threshold = 95
when :matterhorn
Rubyhorn.init
+ when :mediaconvert
+ ActiveEncode::Base.engine_adapter.role = Settings.encoding.media_convert.role
+ ActiveEncode::Base.engine_adapter.output_bucket = Settings.encoding.derivative_bucket
+ ActiveEncode::Base.engine_adapter.setup!
when :elastic_transcoder
require 'aws-sdk-elastictranscoder'
require 'avalon/elastic_transcoder_encode'
diff --git a/config/initializers/active_fedora_env.rb b/config/initializers/active_fedora_env.rb
index 0ddccbe616..32e00d05cb 100644
--- a/config/initializers/active_fedora_env.rb
+++ b/config/initializers/active_fedora_env.rb
@@ -11,11 +11,12 @@ def load_fedora_config
if fedora_setting.present?
ActiveFedora::Base.logger.info("ActiveFedora: loading fedora config from FEDORA_URL") if ActiveFedora::Base.logger
fedora_url = URI.parse(fedora_setting)
- @fedora_config = { user: fedora_url.user, password: fedora_url.password, base_path: ENV['FEDORA_BASE_PATH'] || "" }
+ @fedora_config = { user: fedora_url.user, password: fedora_url.password, base_path: ERB.new(Settings.fedora&.base_path || ENV['FEDORA_BASE_PATH'] || "").result }
fedora_url.userinfo = ''
@fedora_config[:url] = fedora_url.to_s
@fedora_config[:request] = { timeout: Float(fedora_timeout), open_timeout: Float(fedora_timeout) } unless fedora_timeout.blank?
- ENV['FEDORA_URL'] ||= fedora_setting
+ ENV['FEDORA_URL'] ||= @fedora_config[:url]
+ ENV['FEDORA_BASE_PATH'] ||= @fedora_config[:base_path]
else
super
end
@@ -29,8 +30,8 @@ def load_solr_config
solr_setting = Settings.solr_url || ENV['SOLR_URL']
if solr_setting.present?
ActiveFedora::Base.logger.info("ActiveFedora: loading solr config from SOLR_URL") if ActiveFedora::Base.logger
- @solr_config = { url: solr_setting }
- ENV['SOLR_URL'] ||= solr_setting
+ @solr_config = { url: ERB.new(solr_setting).result }
+ ENV['SOLR_URL'] ||= @solr_config[:url]
else
super
end
diff --git a/config/initializers/avalon_lti.rb b/config/initializers/avalon_lti.rb
index 3dee05d751..54cf821d86 100644
--- a/config/initializers/avalon_lti.rb
+++ b/config/initializers/avalon_lti.rb
@@ -1,11 +1,13 @@
# You also need to explicitly enable OAuth 1 support in the environment.rb or an initializer:
AUTH_10_SUPPORT = true
+OAuth::Signature.available_methods.keys.each do |method|
+ OAuth::Signature.available_methods[method.upcase] = OAuth::Signature.available_methods[method]
+end
module Avalon
module Lti
begin
- Configuration =
- YAML.load(ERB.new(File.read(File.expand_path('../../lti.yml', __FILE__))).result)
+ Configuration = YAML.load(File.read(File.expand_path('../../lti.yml',__FILE__)))
rescue
Configuration = {}
end
diff --git a/config/initializers/aws.rb b/config/initializers/aws.rb
index ff540a99fe..8fc0b6c010 100644
--- a/config/initializers/aws.rb
+++ b/config/initializers/aws.rb
@@ -2,12 +2,23 @@
require "aws-sdk-s3"
Aws.config.update(
+ s3: {
endpoint: Settings.minio.endpoint,
access_key_id: Settings.minio.access,
secret_access_key: Settings.minio.secret,
region: ENV["AWS_REGION"]
+ }
)
-
# Service specific global configuration
Aws.config[:s3] = { force_path_style: true }
end
+
+if Settings.sqs
+ require "aws-sdk-sqs"
+ Aws.config.update(
+ sqs: {
+ endpoint: Settings.sqs ? Settings.sqs.endpoint : nil,
+ region: ENV["AWS_REGION"]
+ }
+ )
+end
diff --git a/config/initializers/cache_store.rb b/config/initializers/cache_store.rb
index 699940c3b0..80b5f34ac4 100644
--- a/config/initializers/cache_store.rb
+++ b/config/initializers/cache_store.rb
@@ -3,10 +3,18 @@
redis_host = Settings.redis.host
redis_port = Settings.redis.port || 6379
redis_db = Settings.redis.db || 0
+
+Redis.new(host: Settings.redis.host, port: Settings.redis.port).tap do |redis|
+ (setting, value) = redis.config("GET", "replica-read-only")
+ if value == "yes"
+ redis.config("SET", "replica-read-only", "no")
+ end
+rescue Redis::CannotConnectError, Redis::CommandError
+ # Don't worry about it
+end
+
config.cache_store = :redis_store, {
host: redis_host,
port: redis_port,
- db: redis_db,
- namespace: 'avalon'
+ db: redis_db
}
-
diff --git a/config/initializers/config.rb b/config/initializers/config.rb
index c51f6429f0..acea97f355 100644
--- a/config/initializers/config.rb
+++ b/config/initializers/config.rb
@@ -11,7 +11,7 @@
# config.overwrite_arrays = true
# Load environment variables from the `ENV` object and override any settings defined in files.
- config.use_env = true
+ config.use_env = true unless Rails.env.test?
# Define ENV variable prefix deciding which variables to load into config.
config.env_prefix = 'SETTINGS'
diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb
index c94cefe824..4dec934450 100644
--- a/config/initializers/devise.rb
+++ b/config/initializers/devise.rb
@@ -1,354 +1,353 @@
-Rails.application.reloader.to_prepare do
- # Use this hook to configure devise mailer, warden hooks and so forth.
- # Many of these configuration options can be set straight in your model.
- Devise.setup do |config|
- # The secret key used by Devise. Devise uses this key to generate
- # random tokens. Changing this key will render invalid all existing
- # confirmation, reset password and unlock tokens in the database.
- # Devise will use the `secret_key_base` as its `secret_key`
- # by default. You can change it below and use your own secret key.
- # config.secret_key = '954891a731718dd9c577d1be0d85c6f4bae4dbd43a82864954ad82523ba708317b28d3c5a7cde5288cddea43884a87c16d6501678fc92426599c6d9277c8aec5'
-
- # ==> Mailer Configuration
- # Configure the e-mail address which will be shown in Devise::Mailer,
- # note that it will be overwritten if you use your own mailer class
- # with default "from" parameter.
- config.mailer_sender = Settings.email.notification
-
- # Configure the class responsible to send e-mails.
- # config.mailer = 'Devise::Mailer'
-
- # Configure the parent class responsible to send e-mails.
- # config.parent_mailer = 'ActionMailer::Base'
-
- # ==> ORM configuration
- # Load and configure the ORM. Supports :active_record (default) and
- # :mongoid (bson_ext recommended) by default. Other ORMs may be
- # available as additional gems.
- require 'devise/orm/active_record'
-
- # ==> Configuration for any authentication mechanism
- # Configure which keys are used when authenticating a user. The default is
- # just :email. You can configure it to use [:login, :subdomain], so for
- # authenticating a user, both parameters are required. Remember that those
- # parameters are used only when authenticating and not when retrieving from
- # session. If you need permissions, you should implement that in a before filter.
- # You can also supply a hash where the value is a boolean determining whether
- # or not authentication should be aborted when the value is not present.
- config.authentication_keys = [:username]
-
- # Configure parameters from the request object used for authentication. Each entry
- # given should be a request method and it will automatically be passed to the
- # find_for_authentication method and considered in your model lookup. For instance,
- # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
- # The same considerations mentioned for authentication_keys also apply to request_keys.
- # config.request_keys = []
-
- # Configure which authentication keys should be case-insensitive.
- # These keys will be downcased upon creating or modifying a user and when used
- # to authenticate or find a user. Default is :email.
- config.case_insensitive_keys = [:username, :login, :email]
-
- # Configure which authentication keys should have whitespace stripped.
- # These keys will have whitespace before and after removed upon creating or
- # modifying a user and when used to authenticate or find a user. Default is :email.
- config.strip_whitespace_keys = [:username, :login, :email]
-
- # Tell if authentication through request.params is enabled. True by default.
- # It can be set to an array that will enable params authentication only for the
- # given strategies, for example, `config.params_authenticatable = [:database]` will
- # enable it only for database (email + password) authentication.
- # config.params_authenticatable = true
-
- # Tell if authentication through HTTP Auth is enabled. False by default.
- # It can be set to an array that will enable http authentication only for the
- # given strategies, for example, `config.http_authenticatable = [:database]` will
- # enable it only for database authentication. The supported strategies are:
- # :database = Support basic authentication with authentication key + password
- # config.http_authenticatable = false
-
- # If 401 status code should be returned for AJAX requests. True by default.
- # config.http_authenticatable_on_xhr = true
-
- # The realm used in Http Basic Authentication. 'Application' by default.
- # config.http_authentication_realm = 'Application'
-
- # It will change confirmation, password recovery and other workflows
- # to behave the same regardless if the e-mail provided was right or wrong.
- # Does not affect registerable.
- # config.paranoid = true
-
- # By default Devise will store the user in session. You can skip storage for
- # particular strategies by setting this option.
- # Notice that if you are skipping storage for all authentication paths, you
- # may want to disable generating routes to Devise's sessions controller by
- # passing skip: :sessions to `devise_for` in your config/routes.rb
- config.skip_session_storage = [:http_auth]
-
- # By default, Devise cleans up the CSRF token on authentication to
- # avoid CSRF token fixation attacks. This means that, when using AJAX
- # requests for sign in and sign up, you need to get a new CSRF token
- # from the server. You can disable this option at your own risk.
- # config.clean_up_csrf_token_on_authentication = true
-
- # When false, Devise will not attempt to reload routes on eager load.
- # This can reduce the time taken to boot the app but if your application
- # requires the Devise mappings to be loaded during boot time the application
- # won't boot properly.
- # config.reload_routes = true
-
- # ==> Configuration for :database_authenticatable
- # For bcrypt, this is the cost for hashing the password and defaults to 11. If
- # using other algorithms, it sets how many times you want the password to be hashed.
- #
- # Limiting the stretches to just one in testing will increase the performance of
- # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
- # a value less than 10 in other environments. Note that, for bcrypt (the default
- # algorithm), the cost increases exponentially with the number of stretches (e.g.
- # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
- config.stretches = Rails.env.test? ? 1 : 11
-
- # Set up a pepper to generate the hashed password.
- # config.pepper = '2494a81cfee550c3640539b4bcbfa986f6559011bd05d896d6d6720d6d56a17bd5f3cdab2d975f94c3ae4fa39c07ddae1a07dddc28693caf33a29f01e3fac0d6'
-
- # Send a notification email when the user's password is changed
- # config.send_password_change_notification = false
-
- # ==> Configuration for :invitable
- # The period the generated invitation token is valid, after
- # this period, the invited resource won't be able to accept the invitation.
- # When invite_for is 0 (the default), the invitation won't expire.
- # config.invite_for = 2.weeks
-
- # Number of invitations users can send.
- # - If invitation_limit is nil, there is no limit for invitations, users can
- # send unlimited invitations, invitation_limit column is not used.
- # - If invitation_limit is 0, users can't send invitations by default.
- # - If invitation_limit n > 0, users can send n invitations.
- # You can change invitation_limit column for some users so they can send more
- # or less invitations, even with global invitation_limit = 0
- # Default: nil
- # config.invitation_limit = 5
-
- # The key to be used to check existing users when sending an invitation
- # and the regexp used to test it when validate_on_invite is not set.
- # config.invite_key = {:email => /\A[^@]+@[^@]+\z/}
- # config.invite_key = {:email => /\A[^@]+@[^@]+\z/, :login => nil}
-
- # Flag that force a record to be valid before being actually invited
- # Default: false
- # config.validate_on_invite = true
-
- # Resend invitation if user with invited status is invited again
- # Default: true
- # config.resend_invitation = false
-
- # The class name of the inviting model. If this is nil,
- # the #invited_by association is declared to be polymorphic.
- # Default: nil
- # config.invited_by_class_name = 'User'
-
- # The foreign key to the inviting model (if invited_by_class_name is set)
- # Default: :invited_by_id
- # config.invited_by_foreign_key = :invited_by_id
-
- # The column name used for counter_cache column. If this is nil,
- # the #invited_by association is declared without counter_cache.
- # Default: nil
- # config.invited_by_counter_cache = :invitations_count
-
- # Auto-login after the user accepts the invite. If this is false,
- # the user will need to manually log in after accepting the invite.
- # Default: true
- # config.allow_insecure_sign_in_after_accept = false
-
- # ==> Configuration for :confirmable
- # A period that the user is allowed to access the website even without
- # confirming their account. For instance, if set to 2.days, the user will be
- # able to access the website for two days without confirming their account,
- # access will be blocked just in the third day. Default is 0.days, meaning
- # the user cannot access the website without confirming their account.
- # config.allow_unconfirmed_access_for = 2.days
-
- # A period that the user is allowed to confirm their account before their
- # token becomes invalid. For example, if set to 3.days, the user can confirm
- # their account within 3 days after the mail was sent, but on the fourth day
- # their account can't be confirmed with the token any more.
- # Default is nil, meaning there is no restriction on how long a user can take
- # before confirming their account.
- # config.confirm_within = 3.days
-
- # If true, requires any email changes to be confirmed (exactly the same way as
- # initial account confirmation) to be applied. Requires additional unconfirmed_email
- # db field (see migrations). Until confirmed, new email is stored in
- # unconfirmed_email column, and copied to email column on successful confirmation.
- config.reconfirmable = true
-
- # Defines which key will be used when confirming an account
- # config.confirmation_keys = [:email]
-
- # ==> Configuration for :rememberable
- # The time the user will be remembered without asking for credentials again.
- # config.remember_for = 2.weeks
-
- # Invalidates all the remember me tokens when the user signs out.
- config.expire_all_remember_me_on_sign_out = true
-
- # If true, extends the user's remember period when remembered via cookie.
- # config.extend_remember_period = false
-
- # Options to be passed to the created cookie. For instance, you can set
- # secure: true in order to force SSL only cookies.
- # config.rememberable_options = {}
-
- # ==> Configuration for :validatable
- # Range for password length.
- config.password_length = 6..128
-
- # Email regex used to validate email formats. It simply asserts that
- # one (and only one) @ exists in the given string. This is mainly
- # to give user feedback and not to assert the e-mail validity.
- config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
-
- # ==> Configuration for :timeoutable
- # The time you want to timeout the user session without activity. After this
- # time the user will be asked for credentials again. Default is 30 minutes.
- # config.timeout_in = 30.minutes
-
- # ==> Configuration for :lockable
- # Defines which strategy will be used to lock an account.
- # :failed_attempts = Locks an account after a number of failed attempts to sign in.
- # :none = No lock strategy. You should handle locking by yourself.
- # config.lock_strategy = :failed_attempts
-
- # Defines which key will be used when locking and unlocking an account
- # config.unlock_keys = [:email]
-
- # Defines which strategy will be used to unlock an account.
- # :email = Sends an unlock link to the user email
- # :time = Re-enables login after a certain amount of time (see :unlock_in below)
- # :both = Enables both strategies
- # :none = No unlock strategy. You should handle unlocking by yourself.
- # config.unlock_strategy = :both
-
- # Number of authentication tries before locking an account if lock_strategy
- # is failed attempts.
- # config.maximum_attempts = 20
-
- # Time interval to unlock the account if :time is enabled as unlock_strategy.
- # config.unlock_in = 1.hour
-
- # Warn on the last attempt before the account is locked.
- # config.last_attempt_warning = true
-
- # ==> Configuration for :recoverable
- #
- # Defines which key will be used when recovering the password for an account
- # config.reset_password_keys = [:email]
-
- # Time interval you can reset your password with a reset password key.
- # Don't put a too small interval or your users won't have the time to
- # change their passwords.
- config.reset_password_within = 6.hours
-
- # When set to false, does not sign a user in automatically after their password is
- # reset. Defaults to true, so a user is signed in automatically after a reset.
- # config.sign_in_after_reset_password = true
-
- # ==> Configuration for :encryptable
- # Allow you to use another hashing or encryption algorithm besides bcrypt (default).
- # You can use :sha1, :sha512 or algorithms from others authentication tools as
- # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20
- # for default behavior) and :restful_authentication_sha1 (then you should set
- # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper).
- #
- # Require the `devise-encryptable` gem when using anything other than bcrypt
- # config.encryptor = :sha512
-
- # ==> Scopes configuration
- # Turn scoped views on. Before rendering "sessions/new", it will first check for
- # "users/sessions/new". It's turned off by default because it's slower if you
- # are using only default views.
- # config.scoped_views = false
-
- # Configure the default scope given to Warden. By default it's the first
- # devise role declared in your routes (usually :user).
- # config.default_scope = :user
-
- # Set this configuration to false if you want /users/sign_out to sign out
- # only the current scope. By default, Devise signs out all scopes.
- # config.sign_out_all_scopes = true
-
- # ==> Navigation configuration
- # Lists the formats that should be treated as navigational. Formats like
- # :html, should redirect to the sign in page when the user does not have
- # access, but formats like :xml or :json, should return 401.
- #
- # If you have any extra navigational formats, like :iphone or :mobile, you
- # should add them to the navigational formats lists.
- #
- # The "*/*" below is required to match Internet Explorer requests.
- # config.navigational_formats = ['*/*', :html]
-
- # The default HTTP method used to sign out a resource. Default is :delete.
- config.sign_out_via = :get
-
- # ==> OmniAuth
- # Add a new OmniAuth provider. Check the wiki for more information on setting
- # up on your models and hooks.
- # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
- Avalon::Authentication::Providers.each do |provider|
- if provider[:provider] == :lti
- provider[:params].merge!({consumers: Avalon::Lti::Configuration})
- end
- if provider[:provider] == :identity
- provider[:params].merge!({
- on_login: AuthFormsController.action(:render_identity_request_form),
- on_registration: AuthFormsController.action(:render_identity_registration_form),
- on_failed_registration: AuthFormsController.action(:render_form_with_errors)
- })
- end
- params = provider[:params]
- params = [params] unless params.is_a?(Array)
- begin
- require "omniauth/#{provider[:provider]}"
- rescue LoadError
- require "omniauth-#{provider[:provider]}"
- end
- config.omniauth provider[:provider], *params
+# Use this hook to configure devise mailer, warden hooks and so forth.
+# Many of these configuration options can be set straight in your model.
+Devise.setup do |config|
+ # The secret key used by Devise. Devise uses this key to generate
+ # random tokens. Changing this key will render invalid all existing
+ # confirmation, reset password and unlock tokens in the database.
+ # Devise will use the `secret_key_base` as its `secret_key`
+ # by default. You can change it below and use your own secret key.
+ # config.secret_key = '954891a731718dd9c577d1be0d85c6f4bae4dbd43a82864954ad82523ba708317b28d3c5a7cde5288cddea43884a87c16d6501678fc92426599c6d9277c8aec5'
+
+ # ==> Mailer Configuration
+ # Configure the e-mail address which will be shown in Devise::Mailer,
+ # note that it will be overwritten if you use your own mailer class
+ # with default "from" parameter.
+ config.mailer_sender = Settings.email.notification
+
+ # Configure the class responsible to send e-mails.
+ # config.mailer = 'Devise::Mailer'
+
+ # Configure the parent class responsible to send e-mails.
+ # config.parent_mailer = 'ActionMailer::Base'
+
+ # ==> ORM configuration
+ # Load and configure the ORM. Supports :active_record (default) and
+ # :mongoid (bson_ext recommended) by default. Other ORMs may be
+ # available as additional gems.
+ require 'devise/orm/active_record'
+
+# ==> Configuration for any authentication mechanism
+# Configure which keys are used when authenticating a user. The default is
+# just :email. You can configure it to use [:login, :subdomain], so for
+# authenticating a user, both parameters are required. Remember that those
+# parameters are used only when authenticating and not when retrieving from
+# session. If you need permissions, you should implement that in a before filter.
+# You can also supply a hash where the value is a boolean determining whether
+# or not authentication should be aborted when the value is not present.
+config.authentication_keys = [:email, :username]
+
+ # Configure parameters from the request object used for authentication. Each entry
+ # given should be a request method and it will automatically be passed to the
+ # find_for_authentication method and considered in your model lookup. For instance,
+ # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
+ # The same considerations mentioned for authentication_keys also apply to request_keys.
+ # config.request_keys = []
+
+ # Configure which authentication keys should be case-insensitive.
+ # These keys will be downcased upon creating or modifying a user and when used
+ # to authenticate or find a user. Default is :email.
+ config.case_insensitive_keys = [:username, :login, :email]
+
+ # Configure which authentication keys should have whitespace stripped.
+ # These keys will have whitespace before and after removed upon creating or
+ # modifying a user and when used to authenticate or find a user. Default is :email.
+ config.strip_whitespace_keys = [:username, :login, :email]
+
+ # Tell if authentication through request.params is enabled. True by default.
+ # It can be set to an array that will enable params authentication only for the
+ # given strategies, for example, `config.params_authenticatable = [:database]` will
+ # enable it only for database (email + password) authentication.
+ # config.params_authenticatable = true
+
+ # Tell if authentication through HTTP Auth is enabled. False by default.
+ # It can be set to an array that will enable http authentication only for the
+ # given strategies, for example, `config.http_authenticatable = [:database]` will
+ # enable it only for database authentication. The supported strategies are:
+ # :database = Support basic authentication with authentication key + password
+ # config.http_authenticatable = false
+
+ # If 401 status code should be returned for AJAX requests. True by default.
+ # config.http_authenticatable_on_xhr = true
+
+ # The realm used in Http Basic Authentication. 'Application' by default.
+ # config.http_authentication_realm = 'Application'
+
+ # It will change confirmation, password recovery and other workflows
+ # to behave the same regardless if the e-mail provided was right or wrong.
+ # Does not affect registerable.
+ # config.paranoid = true
+
+ # By default Devise will store the user in session. You can skip storage for
+ # particular strategies by setting this option.
+ # Notice that if you are skipping storage for all authentication paths, you
+ # may want to disable generating routes to Devise's sessions controller by
+ # passing skip: :sessions to `devise_for` in your config/routes.rb
+ config.skip_session_storage = [:http_auth]
+
+ # By default, Devise cleans up the CSRF token on authentication to
+ # avoid CSRF token fixation attacks. This means that, when using AJAX
+ # requests for sign in and sign up, you need to get a new CSRF token
+ # from the server. You can disable this option at your own risk.
+ # config.clean_up_csrf_token_on_authentication = true
+
+ # When false, Devise will not attempt to reload routes on eager load.
+ # This can reduce the time taken to boot the app but if your application
+ # requires the Devise mappings to be loaded during boot time the application
+ # won't boot properly.
+ # config.reload_routes = true
+
+ # ==> Configuration for :database_authenticatable
+ # For bcrypt, this is the cost for hashing the password and defaults to 11. If
+ # using other algorithms, it sets how many times you want the password to be hashed.
+ #
+ # Limiting the stretches to just one in testing will increase the performance of
+ # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
+ # a value less than 10 in other environments. Note that, for bcrypt (the default
+ # algorithm), the cost increases exponentially with the number of stretches (e.g.
+ # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
+ config.stretches = Rails.env.test? ? 1 : 11
+
+ # Set up a pepper to generate the hashed password.
+ # config.pepper = '2494a81cfee550c3640539b4bcbfa986f6559011bd05d896d6d6720d6d56a17bd5f3cdab2d975f94c3ae4fa39c07ddae1a07dddc28693caf33a29f01e3fac0d6'
+
+ # Send a notification email when the user's password is changed
+ # config.send_password_change_notification = false
+
+ # ==> Configuration for :invitable
+ # The period the generated invitation token is valid, after
+ # this period, the invited resource won't be able to accept the invitation.
+ # When invite_for is 0 (the default), the invitation won't expire.
+ # config.invite_for = 2.weeks
+
+ # Number of invitations users can send.
+ # - If invitation_limit is nil, there is no limit for invitations, users can
+ # send unlimited invitations, invitation_limit column is not used.
+ # - If invitation_limit is 0, users can't send invitations by default.
+ # - If invitation_limit n > 0, users can send n invitations.
+ # You can change invitation_limit column for some users so they can send more
+ # or less invitations, even with global invitation_limit = 0
+ # Default: nil
+ # config.invitation_limit = 5
+
+ # The key to be used to check existing users when sending an invitation
+ # and the regexp used to test it when validate_on_invite is not set.
+ # config.invite_key = {:email => /\A[^@]+@[^@]+\z/}
+ # config.invite_key = {:email => /\A[^@]+@[^@]+\z/, :login => nil}
+
+ # Flag that force a record to be valid before being actually invited
+ # Default: false
+ # config.validate_on_invite = true
+
+ # Resend invitation if user with invited status is invited again
+ # Default: true
+ # config.resend_invitation = false
+
+ # The class name of the inviting model. If this is nil,
+ # the #invited_by association is declared to be polymorphic.
+ # Default: nil
+ # config.invited_by_class_name = 'User'
+
+ # The foreign key to the inviting model (if invited_by_class_name is set)
+ # Default: :invited_by_id
+ # config.invited_by_foreign_key = :invited_by_id
+
+ # The column name used for counter_cache column. If this is nil,
+ # the #invited_by association is declared without counter_cache.
+ # Default: nil
+ # config.invited_by_counter_cache = :invitations_count
+
+ # Auto-login after the user accepts the invite. If this is false,
+ # the user will need to manually log in after accepting the invite.
+ # Default: true
+ # config.allow_insecure_sign_in_after_accept = false
+
+ # ==> Configuration for :confirmable
+ # A period that the user is allowed to access the website even without
+ # confirming their account. For instance, if set to 2.days, the user will be
+ # able to access the website for two days without confirming their account,
+ # access will be blocked just in the third day. Default is 0.days, meaning
+ # the user cannot access the website without confirming their account.
+ # config.allow_unconfirmed_access_for = 2.days
+
+ # A period that the user is allowed to confirm their account before their
+ # token becomes invalid. For example, if set to 3.days, the user can confirm
+ # their account within 3 days after the mail was sent, but on the fourth day
+ # their account can't be confirmed with the token any more.
+ # Default is nil, meaning there is no restriction on how long a user can take
+ # before confirming their account.
+ # config.confirm_within = 3.days
+
+ # If true, requires any email changes to be confirmed (exactly the same way as
+ # initial account confirmation) to be applied. Requires additional unconfirmed_email
+ # db field (see migrations). Until confirmed, new email is stored in
+ # unconfirmed_email column, and copied to email column on successful confirmation.
+ config.reconfirmable = true
+
+ # Defines which key will be used when confirming an account
+ # config.confirmation_keys = [:email]
+
+ # ==> Configuration for :rememberable
+ # The time the user will be remembered without asking for credentials again.
+ # config.remember_for = 2.weeks
+
+ # Invalidates all the remember me tokens when the user signs out.
+ config.expire_all_remember_me_on_sign_out = true
+
+ # If true, extends the user's remember period when remembered via cookie.
+ # config.extend_remember_period = false
+
+ # Options to be passed to the created cookie. For instance, you can set
+ # secure: true in order to force SSL only cookies.
+ # config.rememberable_options = {}
+
+ # ==> Configuration for :validatable
+ # Range for password length.
+ config.password_length = 6..128
+
+ # Email regex used to validate email formats. It simply asserts that
+ # one (and only one) @ exists in the given string. This is mainly
+ # to give user feedback and not to assert the e-mail validity.
+ config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
+
+ # ==> Configuration for :timeoutable
+ # The time you want to timeout the user session without activity. After this
+ # time the user will be asked for credentials again. Default is 30 minutes.
+ # config.timeout_in = 30.minutes
+
+ # ==> Configuration for :lockable
+ # Defines which strategy will be used to lock an account.
+ # :failed_attempts = Locks an account after a number of failed attempts to sign in.
+ # :none = No lock strategy. You should handle locking by yourself.
+ # config.lock_strategy = :failed_attempts
+
+ # Defines which key will be used when locking and unlocking an account
+ # config.unlock_keys = [:email]
+
+ # Defines which strategy will be used to unlock an account.
+ # :email = Sends an unlock link to the user email
+ # :time = Re-enables login after a certain amount of time (see :unlock_in below)
+ # :both = Enables both strategies
+ # :none = No unlock strategy. You should handle unlocking by yourself.
+ # config.unlock_strategy = :both
+
+ # Number of authentication tries before locking an account if lock_strategy
+ # is failed attempts.
+ # config.maximum_attempts = 20
+
+ # Time interval to unlock the account if :time is enabled as unlock_strategy.
+ # config.unlock_in = 1.hour
+
+ # Warn on the last attempt before the account is locked.
+ # config.last_attempt_warning = true
+
+ # ==> Configuration for :recoverable
+ #
+ # Defines which key will be used when recovering the password for an account
+ # config.reset_password_keys = [:email]
+
+ # Time interval you can reset your password with a reset password key.
+ # Don't put a too small interval or your users won't have the time to
+ # change their passwords.
+ config.reset_password_within = 6.hours
+
+ # When set to false, does not sign a user in automatically after their password is
+ # reset. Defaults to true, so a user is signed in automatically after a reset.
+ # config.sign_in_after_reset_password = true
+
+ # ==> Configuration for :encryptable
+ # Allow you to use another hashing or encryption algorithm besides bcrypt (default).
+ # You can use :sha1, :sha512 or algorithms from others authentication tools as
+ # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20
+ # for default behavior) and :restful_authentication_sha1 (then you should set
+ # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper).
+ #
+ # Require the `devise-encryptable` gem when using anything other than bcrypt
+ # config.encryptor = :sha512
+
+ # ==> Scopes configuration
+ # Turn scoped views on. Before rendering "sessions/new", it will first check for
+ # "users/sessions/new". It's turned off by default because it's slower if you
+ # are using only default views.
+ # config.scoped_views = false
+
+ # Configure the default scope given to Warden. By default it's the first
+ # devise role declared in your routes (usually :user).
+ # config.default_scope = :user
+
+ # Set this configuration to false if you want /users/sign_out to sign out
+ # only the current scope. By default, Devise signs out all scopes.
+ # config.sign_out_all_scopes = true
+
+ # ==> Navigation configuration
+ # Lists the formats that should be treated as navigational. Formats like
+ # :html, should redirect to the sign in page when the user does not have
+ # access, but formats like :xml or :json, should return 401.
+ #
+ # If you have any extra navigational formats, like :iphone or :mobile, you
+ # should add them to the navigational formats lists.
+ #
+ # The "*/*" below is required to match Internet Explorer requests.
+ # config.navigational_formats = ['*/*', :html]
+
+ # The default HTTP method used to sign out a resource. Default is :delete.
+ config.sign_out_via = :get
+
+ # ==> OmniAuth
+ # Add a new OmniAuth provider. Check the wiki for more information on setting
+ # up on your models and hooks.
+ # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
+
+ Avalon::Authentication::Providers.each do |provider|
+ if provider[:provider] == :lti
+ provider[:params].merge!({consumers: Avalon::Lti::Configuration})
end
-
- # ==> Warden configuration
- # If you want to use other strategies, that are not supported by Devise, or
- # change the failure app, you can configure them inside the config.warden block.
- #
- # config.warden do |manager|
- # manager.intercept_401 = false
- # manager.default_strategies(scope: :user).unshift :some_external_strategy
- # end
-
- # ==> Mountable engine configurations
- # When using Devise inside an engine, let's call it `MyEngine`, and this engine
- # is mountable, there are some extra configurations to be taken into account.
- # The following options are available, assuming the engine is mounted as:
- #
- # mount MyEngine, at: '/my_engine'
- #
- # The router that invoked `devise_for`, in the example above, would be:
- # config.router_name = :my_engine
- #
- # When using OmniAuth, Devise cannot automatically set OmniAuth path,
- # so you need to do it manually. For the users scope, it would be:
- # config.omniauth_path_prefix = '/my_engine/users/auth'
- OmniAuth.config.logger = Rails.logger
+ if provider[:provider] == :identity
+ provider[:params].merge!({
+ on_login: AuthFormsController.action(:render_identity_request_form),
+ on_registration: AuthFormsController.action(:render_identity_registration_form),
+ on_failed_registration: AuthFormsController.action(:render_form_with_errors)
+ })
+ end
+ params = provider[:params]
+ params = [params] unless params.is_a?(Array)
+ begin
+ require "omniauth/#{provider[:provider]}"
+ rescue LoadError
+ require "omniauth-#{provider[:provider]}"
+ end
+ config.omniauth provider[:provider], *params
end
- # Override script_name to always return empty string and avoid looking in @env
- # This override is needed due to our direct rendering of the identity login form in AuthFormsController
- # which doesn't initialize @env leading to a NoMethodError when trying read a hash value from it.
- OmniAuth::Strategies::Identity.class_eval do
- def script_name
- ''
- end
+ # ==> Warden configuration
+ # If you want to use other strategies, that are not supported by Devise, or
+ # change the failure app, you can configure them inside the config.warden block.
+ #
+ # config.warden do |manager|
+ # manager.intercept_401 = false
+ # manager.default_strategies(scope: :user).unshift :some_external_strategy
+ # end
+
+ # ==> Mountable engine configurations
+ # When using Devise inside an engine, let's call it `MyEngine`, and this engine
+ # is mountable, there are some extra configurations to be taken into account.
+ # The following options are available, assuming the engine is mounted as:
+ #
+ # mount MyEngine, at: '/my_engine'
+ #
+ # The router that invoked `devise_for`, in the example above, would be:
+ # config.router_name = :my_engine
+ #
+ # When using OmniAuth, Devise cannot automatically set OmniAuth path,
+ # so you need to do it manually. For the users scope, it would be:
+ # config.omniauth_path_prefix = '/my_engine/users/auth'
+ OmniAuth.config.logger = Rails.logger
+end
+
+# Override script_name to always return empty string and avoid looking in @env
+# This override is needed due to our direct rendering of the identity login form in AuthFormsController
+# which doesn't initialize @env leading to a NoMethodError when trying read a hash value from it.
+OmniAuth::Strategies::Identity.class_eval do
+ def script_name
+ ''
end
end
diff --git a/config/initializers/logging_config.rb b/config/initializers/logging_config.rb
new file mode 100644
index 0000000000..323f2d192f
--- /dev/null
+++ b/config/initializers/logging_config.rb
@@ -0,0 +1 @@
+Rails.logger.level = Settings.log_level.to_sym unless Settings.log_level.nil?
diff --git a/config/initializers/media_convert_config.rb b/config/initializers/media_convert_config.rb
new file mode 100644
index 0000000000..0eab17714d
--- /dev/null
+++ b/config/initializers/media_convert_config.rb
@@ -0,0 +1,20 @@
+Settings.encoding.media_convert ||= Config::Options.new
+Settings.encoding.media_convert.configuration = {
+ mapping: {'720' => 'high', '540' => 'low'},
+ options: {
+ 'avalon' => {
+ media_type: :video,
+ outputs: [
+ {preset: "avr-video-medium", modifier: "-720"},
+ {preset: "avr-video-low", modifier: "-540"}
+ ]
+ },
+ 'fullaudio' => {
+ media_type: :audio,
+ outputs: [
+ {preset: "avr-audio-high", modifier: "-high"},
+ {preset: "avr-audio-medium", modifier: "-medium"}
+ ]
+ }
+ }
+}
\ No newline at end of file
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
new file mode 100644
index 0000000000..94a441b049
--- /dev/null
+++ b/config/initializers/omniauth.rb
@@ -0,0 +1,4 @@
+OmniAuth.configure do |config|
+ config.allowed_request_methods << :get
+ config.silence_get_warning = true
+end
\ No newline at end of file
diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb
index f669ba1e7e..f3e0da32f7 100644
--- a/config/initializers/sidekiq.rb
+++ b/config/initializers/sidekiq.rb
@@ -13,15 +13,14 @@
Sidekiq::Web.disable(:sessions)
require 'sidekiq/cron/web'
-Rails.application.config.to_prepare do
- begin
- # Only create cron jobs if Sidekiq can connect to Redis
- Sidekiq.redis(&:info)
- Sidekiq::Cron::Job.create(name: 'Scan for batches - every 1min', cron: '*/1 * * * *', class: 'BatchScanJob')
- Sidekiq::Cron::Job.create(name: 'Status Checking and Email Notification of Existing Batches - every 15min', cron: '*/15 * * * *', class: 'IngestBatchStatusEmailJobs::IngestFinished')
- Sidekiq::Cron::Job.create(name: 'Status Checking and Email Notification for Stalled Batches - every 1day', cron: '0 1 * * *', class: 'IngestBatchStatusEmailJobs::StalledJob')
- Sidekiq::Cron::Job.create(name: 'Clean out user sessions older than 7 days - every 6hour', cron: '0 */6 * * *', class: 'CleanupSessionJob')
- rescue Redis::CannotConnectError => e
- Rails.logger.warn "Cannot create sidekiq-cron jobs: #{e.message}"
- end
-end
+
+# begin
+# # Only create cron jobs if Sidekiq can connect to Redis
+# Sidekiq.redis(&:info)
+# Sidekiq::Cron::Job.create(name: 'Scan for batches - every 1min', cron: '*/1 * * * *', class: 'BatchScanJob')
+# Sidekiq::Cron::Job.create(name: 'Status Checking and Email Notification of Existing Batches - every 15min', cron: '*/15 * * * *', class: 'IngestBatchStatusEmailJobs::IngestFinished')
+# Sidekiq::Cron::Job.create(name: 'Status Checking and Email Notification for Stalled Batches - every 1day', cron: '0 1 * * *', class: 'IngestBatchStatusEmailJobs::StalledJob')
+# Sidekiq::Cron::Job.create(name: 'Clean out user sessions older than 7 days - every 6hour', cron: '0 */6 * * *', class: 'CleanupSessionJob')
+# rescue Redis::CannotConnectError => e
+# Rails.logger.warn "Cannot create sidekiq-cron jobs: #{e.message}"
+# end
diff --git a/config/lti.yml b/config/lti.yml
new file mode 100644
index 0000000000..85151147be
--- /dev/null
+++ b/config/lti.yml
@@ -0,0 +1,16 @@
+---
+e3285bfcd6cb4332a84aa14da6a3eaad:
+ :uid: :user_id
+ :email: :lis_person_contact_email_primary
+ :context_id: :context_id
+ :context_name: :context_title
+7db438071375c02373713c12c73869ff2f470b68.new-northwestern.instructure.com:
+ :uid: :lis_person_sourcedid
+ :email: :lis_person_contact_email_primary
+ :context_id: :context_label
+ :context_name: :context_title
+avalon.ares.atlas-sys.com:
+ :uid: :lis_person_sourcedid
+ :email: :lis_person_contact_email_primary
+ :context_id: :context_id
+ :context_name: :context_title
diff --git a/config/nu_vocab.yml b/config/nu_vocab.yml
new file mode 100644
index 0000000000..ab6806f3d7
--- /dev/null
+++ b/config/nu_vocab.yml
@@ -0,0 +1,44 @@
+units:
+ - Charles Deering McCormick Library of Special Collections
+ - Center for Scholarly Communication and Digital Curation
+ - Galter Health Sciences Library, Special Collections
+ - Melville J. Herskovits Library of African Studies
+ - Music Library
+ - Northwestern University Archives
+ - Northwestern University Libraries
+ - Northwestern University Pritzker Legal Research Center
+ - Northwestern University Transportation Library
+ - Marjorie I. Mitchell Multimedia Center
+ - WCAS Multimedia Learning Center
+identifier_types:
+ local: Catalog Key
+ oclc: OCLC
+ lccn: LCCN
+ issue number: Issue Number
+ matrix number: Matrix Number
+ music publisher: Music Publisher/Label
+ videorecording identifier: Videorecording Identifier
+ other: Other
+note_types:
+ general: General Note
+ awards: Awards
+ biographical/historical: Biographical/Historical Note
+ creation/production credits: Creation/Production Credits
+ language: Language Note
+ local: Local Note
+ performers: Performers
+ statement of responsibility: Statement of Responsibility
+ venue: Venue/Event Date
+rights_statements:
+ http://rightsstatements.org/vocab/InC/1.0/: In Copyright
+ http://rightsstatements.org/vocab/InC-OW-EU/1.0/: In Copyright - EU Orphan Work
+ http://rightsstatements.org/vocab/InC-EDU/1.0/: In Copyright - Educational Use Permitted
+ http://rightsstatements.org/vocab/InC-NC/1.0/: In Copyright - Non-Commercial Use Permitted
+ http://rightsstatements.org/vocab/InC-RUU/1.0/: In Copyright - Rights-Holders Unlocatable or Unidentifiable
+ http://rightsstatements.org/vocab/NoC-CR/1.0/: No Copyright - Contractual Restrictions
+ http://rightsstatements.org/vocab/NoC-NC/1.0/: No Copyright - Non-Commercial Use Only
+ http://rightsstatements.org/vocab/NoC-OKLR/1.0/: No Copyright - Other Known Legal Restrictions
+ http://rightsstatements.org/vocab/NoC-US/1.0/: No Copyright - United States
+ http://rightsstatements.org/vocab/CNE/1.0/: Copyright Not Evaluated
+ http://rightsstatements.org/vocab/UND/1.0/: Copyright Undetermined
+ http://rightsstatements.org/vocab/NKC/1.0/: No Known Copyright
diff --git a/config/puma.rb b/config/puma.rb
new file mode 100644
index 0000000000..2f32227c90
--- /dev/null
+++ b/config/puma.rb
@@ -0,0 +1,4 @@
+bind 'tcp://0.0.0.0:3000'
+ssl_bind '0.0.0.0', '3001',
+ cert: ENV['SSL_CERT'],
+ key: ENV['SSL_KEY']
\ No newline at end of file
diff --git a/config/puma_container.rb b/config/puma_container.rb
new file mode 100644
index 0000000000..4ba0da7950
--- /dev/null
+++ b/config/puma_container.rb
@@ -0,0 +1,4 @@
+threads 8, 32
+workers `grep -c processor /proc/cpuinfo`
+port ENV.fetch('PORT') { 3000 }
+pidfile '/var/run/puma/puma.pid'
diff --git a/config/resque.yml b/config/resque.yml
index 7ce20cff98..ea6c7dc47f 100644
--- a/config/resque.yml
+++ b/config/resque.yml
@@ -1,2 +1,2 @@
-development: localhost:6379
-test: localhost:6379
+development: localhost:<%= ENV['REDIS_DEV_PORT'] || 6379 %>
+test: localhost:<%= ENV['REDIS_TEST_PORT'] || 6379 %>
diff --git a/config/routes.rb b/config/routes.rb
index d9d6e7c836..ee843671ca 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -62,9 +62,6 @@
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks', sessions: 'users/sessions' }
devise_scope :user do
match '/users/auth/:provider', to: 'users/omniauth_callbacks#passthru', as: :user_omniauth_authorize, via: [:get, :post]
- Avalon::Authentication::Providers.collect { |provider| provider[:provider] }.uniq.each do |provider_name|
- match "/users/auth/#{provider_name}/callback", to: "users/omniauth_callbacks##{provider_name}", as: "user_omniauth_callback_#{provider_name}".to_sym, via: [:get, :post]
- end
end
mount BrowseEverything::Engine => '/browse'
diff --git a/config/settings.yml b/config/settings.yml
index 5b5b039022..5d576b75f6 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -51,7 +51,7 @@ app_job:
solr_and_fedora:
raise_on_connection_error: true
zookeeper:
- connection_str: "localhost:9983/configs"
+ connection_str: 'localhost:9983/configs'
streaming:
server: :generic
stream_token_ttl: 20 #minutes
@@ -91,7 +91,6 @@ auth:
# :params:
# :oauth_credentials:
# somekey: somesecret
-# google_analytics_tracking_id: "someid"
supplemental_files:
proxy: false
waveform:
diff --git a/config/settings/production.yml b/config/settings/production.yml
index e69de29bb2..53eda17b81 100644
--- a/config/settings/production.yml
+++ b/config/settings/production.yml
@@ -0,0 +1,2 @@
+controlled_vocabulary:
+ path: config/nu_vocab.yml
\ No newline at end of file
diff --git a/config/settings/test.yml b/config/settings/test.yml
index 329396e22c..64a79ef26a 100644
--- a/config/settings/test.yml
+++ b/config/settings/test.yml
@@ -14,3 +14,5 @@ encoding:
engine_adapter: test
email:
mailer:
+zookeeper:
+ connection_str: "localhost:9985/configs"
diff --git a/config/shoryuken.yml.erb b/config/shoryuken.yml.erb
new file mode 100644
index 0000000000..835d09d120
--- /dev/null
+++ b/config/shoryuken.yml.erb
@@ -0,0 +1,6 @@
+---
+concurrency: 20
+queues:
+<% queue_names.each do |queue_name| %>
+ - ['<%=queue_name%>', 1]
+<% end %>
\ No newline at end of file
diff --git a/db/migrate/20220518181640_create_redirects.rb b/db/migrate/20220518181640_create_redirects.rb
new file mode 100644
index 0000000000..3874954690
--- /dev/null
+++ b/db/migrate/20220518181640_create_redirects.rb
@@ -0,0 +1,9 @@
+class CreateRedirects < ActiveRecord::Migration[5.2]
+ def change
+ create_table :redirects, id: false do |t|
+ t.string :id, null: false, primary_key: true
+ t.string :item_target, null: false
+ t.string :embed_target, null: true
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index fba55dcffe..a686f36729 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -205,6 +205,11 @@
t.index ["user_id"], name: "index_playlists_on_user_id"
end
+ create_table "redirects", id: :string, force: :cascade do |t|
+ t.string "item_target", null: false
+ t.string "embed_target"
+ end
+
create_table "role_maps", force: :cascade do |t|
t.string "entry"
t.integer "parent_id"
diff --git a/docker-compose.yml b/docker-compose.yml
index ee77c7a422..b76be2bf1d 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,36 +1,43 @@
+---
version: '3.4'
-
volumes:
- database:
fedora:
+ db:
+ goaws:
+ minio:
solr:
- npms:
- data:
-
-networks:
- internal:
- external:
-
services:
db: &db-avalon
image: postgres:14-alpine
+ restart: unless-stopped
+ read_only: true
volumes:
- - database:/data
+ - type: volume
+ source: db
+ target: /data
+ - type: volume
+ target: /tmp
+ - type: volume
+ target: /var/log
+ - type: volume
+ target: /var/run
environment:
- - PGDATA=/data
- - POSTGRES_USER=postgres
- - POSTGRES_DB=avalon
- - POSTGRES_PASSWORD=password
- networks:
- internal:
- db-test:
- <<: *db-avalon
- volumes: []
-
- fedora: &fedora
- image: avalonmediasystem/fedora:4.7.5
- depends_on:
- - db
+ - PGDATA=/data
+ - POSTGRES_USER=docker
+ - POSTGRES_PASSWORD=d0ck3r
+ ports:
+ - 5433:5432
+ - 5434:5432
+ command: postgres -c max_connections=300
+ healthcheck:
+ test: "CMD echo 'SELECT 1' | PGPASSWORD=d0ck3r psql --host 127.0.0.1 --username docker --dbname docker --quiet --no-align --tuples-only"
+ interval: 30s
+ timeout: 5s
+ retries: 3
+ fedora:
+ image: samvera/fcrepo4:4.7.5
+ restart: unless-stopped
+ read_only: true
volumes:
- fedora:/data
environment:
@@ -173,17 +180,37 @@ services:
MINIO_ACCESS_KEY: minio
MINIO_SECRET_KEY: minio123
volumes:
- - data:/data
+ - type: volume
+ source: minio
+ target: /data
+ - type: volume
+ target: /root/.minio
+ - type: bind
+ source: $HOME/.dev_cert/dev.rdc.cert.pem
+ target: /root/.minio/certs/public.crt
+ - type: bind
+ source: $HOME/.dev_cert/dev.rdc.key.pem
+ target: /root/.minio/certs/private.key
+ - type: volume
+ target: /tmp
+ - type: volume
+ target: /var/log
+ - type: volume
+ target: /var/run
ports:
- 9000:9000
- 9090:9090
networks:
- internal:
- external:
+ default:
+ aliases:
+ - ${DEV_PREFIX}.dev.rdc.library.northwestern.edu
healthcheck:
- test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
+ test:
+ - CMD
+ - curl
+ - https://${DEV_PREFIX}.dev.rdc.library.northwestern.edu:9001/minio/health/live
interval: 30s
- timeout: 20s
+ timeout: 5s
retries: 3
createbuckets:
diff --git a/extras/goaws/dev.yml b/extras/goaws/dev.yml
new file mode 100644
index 0000000000..1b2eb1f3d7
--- /dev/null
+++ b/extras/goaws/dev.yml
@@ -0,0 +1,15 @@
+Local:
+ Host: localhost
+ Port: 4101
+ Region:
+ AccountId: "100010001000"
+ LogToFile: false
+ LogFile: .st/goaws_messages.log
+ QueueAttributeDefaults:
+ VisibilityTimeout: 30
+ ReceiveMessageWaitTimeSeconds: 0
+ Queues: []
+ Topics: []
+ RandomLatency:
+ Min: 0
+ Max: 0
diff --git a/extras/goaws/test.yml b/extras/goaws/test.yml
new file mode 100644
index 0000000000..33989adc7b
--- /dev/null
+++ b/extras/goaws/test.yml
@@ -0,0 +1,15 @@
+Local:
+ Host: localhost
+ Port: 4102
+ Region:
+ AccountId: "100010001000"
+ LogToFile: false
+ LogFile: .st/goaws_messages.log
+ QueueAttributeDefaults:
+ VisibilityTimeout: 30
+ ReceiveMessageWaitTimeSeconds: 0
+ Queues: []
+ Topics: []
+ RandomLatency:
+ Min: 0
+ Max: 0
diff --git a/lib/avalon/batch/ingest.rb b/lib/avalon/batch/ingest.rb
index 29cd6d0c16..e6722a30a5 100644
--- a/lib/avalon/batch/ingest.rb
+++ b/lib/avalon/batch/ingest.rb
@@ -60,8 +60,11 @@ def process_valid_package(package: nil)
# Otherwise this should be set
# Validate the package if a side package is passed in
unless package.nil?
- return unless valid_package?
@current_package = package
+ unless valid_package?
+ @current_package = nil
+ return
+ end
end
# We have a valid batch so we can go ahead and delete the manifest file
diff --git a/lib/avalon/batch/package.rb b/lib/avalon/batch/package.rb
index 9b26869c29..b928010a59 100644
--- a/lib/avalon/batch/package.rb
+++ b/lib/avalon/batch/package.rb
@@ -36,7 +36,7 @@ def title
def user
@user ||=
- User.where(Devise.authentication_keys.first => @manifest.email).first ||
+ User.find_by_devise_authentication_keys(@manifest.email).first ||
User.where(username: @manifest.email).first ||
User.where(email: @manifest.email).first
@user
diff --git a/lib/avalon/bib_retriever/sru.rb b/lib/avalon/bib_retriever/sru.rb
index 5b766715b7..ca76bf4464 100644
--- a/lib/avalon/bib_retriever/sru.rb
+++ b/lib/avalon/bib_retriever/sru.rb
@@ -35,7 +35,7 @@ def get_record(bib_id)
def url_for(query, bib_id)
uri = Addressable::URI.parse config['url']
- query_param = Addressable::URI.escape(query % { bib_id: bib_id.to_s })
+ query_param = Addressable::URI.escape_component(query % { bib_id: bib_id.to_s })
uri.query = "version=1.1&operation=searchRetrieve&maximumRecords=1&recordSchema=marcxml&query=#{query_param}"
uri.to_s
end
diff --git a/lib/tasks/avalon.rake b/lib/tasks/avalon.rake
index 9fc749440d..a55b1408e8 100644
--- a/lib/tasks/avalon.rake
+++ b/lib/tasks/avalon.rake
@@ -145,7 +145,7 @@ namespace :avalon do
username = ENV['avalon_username'].dup
groups = Avalon::RoleControls.user_roles username
- User.where(Devise.authentication_keys.first => username).destroy_all
+ User.find_by_devise_authentication_keys(username).destroy_all
groups.each do |group|
Avalon::RoleControls.remove_user_role(username, group)
end
@@ -274,7 +274,7 @@ namespace :avalon do
# Save existing playlist/item/marker data for users being imported
puts "Compiling existing avalon marker data"
usernames = import_json.collect{|user|user['username']}
- userids = User.where(Devise.authentication_keys.first => usernames).collect(&:id)
+ userids = User.find_by_devise_authentication_keys(usernames).collect(&:id)
userids.each do |user_id|
print "."
playlist = Playlist.where(user_id: user_id, title:'Variations Bookmarks').first
diff --git a/lib/tasks/avr.rake b/lib/tasks/avr.rake
new file mode 100644
index 0000000000..ccf1e17c0a
--- /dev/null
+++ b/lib/tasks/avr.rake
@@ -0,0 +1,32 @@
+namespace :avr do
+ desc "Prepare the AVR environment"
+ task :setup do
+ ['zookeeper:upload', 'zookeeper:create', 'db:create', 'db:migrate'].each do |task|
+ Rake::Task[task].invoke
+ end
+
+ begin
+ Rake::Task['avalon:reindex'].invoke
+ rescue
+ end
+ end
+
+ desc "Completely reset the AVR environment"
+ task :reset do
+ Rake::Task['avr:setup'].invoke
+
+ ENV['CONFIRM'] = 'yes'
+ $stderr.puts("Wiping DB, Fedora, Solr, and Redis")
+ Rake::Task['avalon:wipeout'].invoke
+
+ $stderr.puts("Emptying derivatives bucket")
+ Aws::S3::Bucket.new(Settings.encoding.derivative_bucket).objects.each(&:delete)
+ $stderr.puts("Emptying masterfiles bucket")
+ Aws::S3::Bucket.new(Settings.encoding.masterfile_bucket).objects.each(&:delete)
+
+ $stderr.puts("Recreating Fedora root resource path")
+ ActiveFedora.fedora.connection.tap do |conn|
+ conn.head(conn.root_resource_path)
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/tasks/shoryuken.rake b/lib/tasks/shoryuken.rake
new file mode 100644
index 0000000000..717b874da3
--- /dev/null
+++ b/lib/tasks/shoryuken.rake
@@ -0,0 +1,36 @@
+# ActiveJob and ActionMailer handle queue names and prefixes differently, so
+# we need to make allowances for the fact that ActiveJob queue names will
+# already have their prefixes while ActionMailer queue names will not
+
+require 'aws-sdk-sqs'
+
+namespace :shoryuken do
+ desc "Create shoryuken config file"
+ task create_config: :environment do
+ Rails.root.glob('app/jobs/**/*').each { |file| load file }
+ active_job_config = Rails.application.config.active_job
+ prefix = active_job_config.queue_name_prefix.to_s + active_job_config.queue_name_delimiter.to_s
+ queue_names = ActiveJob::Base.descendants.collect do |job_class|
+ queue_name = job_class.queue_name || 'default'
+ queue_name = queue_name.call if queue_name.respond_to?(:call)
+ queue_name = 'default' if queue_name.nil?
+ queue_name = prefix + queue_name unless queue_name.start_with?(prefix)
+ queue_name
+ end.uniq
+ template = ERB.new(File.read(Rails.root.join('config/shoryuken.yml.erb')), trim_mode: '<>')
+ File.open(Rails.root.join('config/shoryuken.yml'), 'w') do |config_file|
+ rendered = template.result(binding)
+ config_file.write(rendered)
+ end
+ end
+
+ desc "Create SQS queues for shoryuken"
+ task create_queues: :environment do
+ sqs = Aws::SQS::Client.new
+ shoryuken_config = YAML.load(File.read(Rails.root.join('config/shoryuken.yml')))
+ shoryuken_config["queues"].each do |queue_name, _count|
+ sqs.create_queue(queue_name: queue_name)
+ $stderr.puts "Created #{queue_name}"
+ end
+ end
+end
\ No newline at end of file
diff --git a/lib/tasks/wipeout.rake b/lib/tasks/wipeout.rake
index ce948eac6d..57a00db492 100644
--- a/lib/tasks/wipeout.rake
+++ b/lib/tasks/wipeout.rake
@@ -12,6 +12,8 @@
# specific language governing permissions and limitations under the License.
# --- END LICENSE_HEADER BLOCK ---
+require 'active_fedora/cleaner'
+
def wipeout_fedora
ActiveFedora::Cleaner.clean!
end
diff --git a/package.json b/package.json
index 4f5aa1441a..695229d5ac 100644
--- a/package.json
+++ b/package.json
@@ -59,5 +59,6 @@
"start-collection-view": "webpack-dev-server --mode development --config config/webpack/collection_view.js --host 0.0.0.0",
"cypress:open": "cypress open -C spec/cypress/cypress.config.js",
"cypress:run": "cypress run -C spec/cypress/cypress.config.js"
- }
+ },
+ "packageManager": "yarn@1.2.2"
}
diff --git a/solr/config/schema.xml b/solr/config/schema.xml
index dbd9cbc8d8..3f6d39aa85 100644
--- a/solr/config/schema.xml
+++ b/solr/config/schema.xml
@@ -165,6 +165,7 @@
+
-
-
+
+
@@ -349,8 +352,10 @@
+