From d17e7db8df8888f8391bdc7ee59dc4393debde65 Mon Sep 17 00:00:00 2001 From: dananji Date: Wed, 22 Mar 2023 11:19:37 -0700 Subject: [PATCH 01/14] Fix no-icon thumbnail height in browse --- app/assets/stylesheets/blacklight.scss | 4 ++++ app/views/catalog/_thumbnail_media_object.html.erb | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/assets/stylesheets/blacklight.scss b/app/assets/stylesheets/blacklight.scss index 93df131ac0..7c1f1c94ca 100644 --- a/app/assets/stylesheets/blacklight.scss +++ b/app/assets/stylesheets/blacklight.scss @@ -22,6 +22,10 @@ max-width: 160px; } +.no-icon img, img.no-icon { + max-height: 90px; +} + .btn-outline-primary { @extend .btn-sm; @extend .btn-outline; diff --git a/app/views/catalog/_thumbnail_media_object.html.erb b/app/views/catalog/_thumbnail_media_object.html.erb index 73131d2455..bc463ad6e6 100644 --- a/app/views/catalog/_thumbnail_media_object.html.erb +++ b/app/views/catalog/_thumbnail_media_object.html.erb @@ -20,6 +20,6 @@ Unless required by applicable law or agreed to in writing, software distributed <%= image_tag( image_url ) %> <% end %> <% else %> - <%= image_tag 'no_icon.png', class: 'result-thumbnail' %> + <%= image_tag 'no_icon.png', class: 'result-thumbnail no-icon' %> <% end %> From 2dd5677c167773b4d0256e6fdd19ee00d84f1993 Mon Sep 17 00:00:00 2001 From: dananji Date: Thu, 23 Mar 2023 13:23:55 -0700 Subject: [PATCH 02/14] Player exception bug fix --- .../media_player_wrapper/avalon_player_new.es6 | 14 +++++++++++--- app/views/media_objects/_item_view.html.erb | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 b/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 index 12765c2587..cbe8da7244 100644 --- a/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 +++ b/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 @@ -399,9 +399,17 @@ class MEJSPlayer { this.mejsUtility.showControlsBriefly(this.player); // Fix for paused seeking halt when using structure navigation // by forcing timeupdate event to fire with a quick and pause - if(this.mediaElement.paused) { - this.mediaElement.play(); - this.mediaElement.pause(); + if(this.mediaElement.paused && this.mediaElement) { + /** Reference: https://developer.chrome.com/blog/play-request-was-interrupted/ */ + let playPromise = this.mediaElement.play(); + if(playPromise !== undefined) { + playPromise.then(_ => { + this.mediaElement.pause(); + }) + .catch(error => { + console.log('Media player error: ', error); + }) + } } } diff --git a/app/views/media_objects/_item_view.html.erb b/app/views/media_objects/_item_view.html.erb index 873654d6ab..9f15f70b3e 100644 --- a/app/views/media_objects/_item_view.html.erb +++ b/app/views/media_objects/_item_view.html.erb @@ -70,7 +70,7 @@ Unless required by applicable law or agreed to in writing, software distributed // When viewing video on smaller devices scroll to page content to fully // display the video player $(document).ready(function () { - const isVideo = "<%= @currentStreamInfo[:is_video] %>"; + const isVideo = <%= @currentStreamInfo[:is_video] %>; if(isVideo) { const screenHeight = screen.height; const playerHeight = document.getElementsByTagName('video')[0].style.height.replace(/[^-\d\.]/g, ''); From bd1112592b5c6a5ff9bb5898b9ffca335d035a69 Mon Sep 17 00:00:00 2001 From: Chris Colvard Date: Mon, 27 Mar 2023 15:27:04 -0400 Subject: [PATCH 03/14] Add executable bit to scripts --- script/avalon_image_tags.rb | 0 script/avalon_version.rb | 0 script/waveform_backfill.rb | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 script/avalon_image_tags.rb mode change 100644 => 100755 script/avalon_version.rb mode change 100644 => 100755 script/waveform_backfill.rb diff --git a/script/avalon_image_tags.rb b/script/avalon_image_tags.rb old mode 100644 new mode 100755 diff --git a/script/avalon_version.rb b/script/avalon_version.rb old mode 100644 new mode 100755 diff --git a/script/waveform_backfill.rb b/script/waveform_backfill.rb old mode 100644 new mode 100755 From 4b2f51e7517f5c70d79475bece704ef2e061ad91 Mon Sep 17 00:00:00 2001 From: Chris Colvard Date: Mon, 27 Mar 2023 16:01:34 -0400 Subject: [PATCH 04/14] Use bugfixed browse-everything --- Gemfile | 2 +- Gemfile.lock | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Gemfile b/Gemfile index 850f7d3aa1..3c222bf03a 100644 --- a/Gemfile +++ b/Gemfile @@ -76,7 +76,7 @@ gem "omniauth-saml", "~> 2.0" # Media Access & Transcoding gem 'active_encode', '~> 1.0', '>= 1.1.2' gem 'audio_waveform-ruby', '~> 1.0.7', require: 'audio_waveform' -gem 'browse-everything', git: "https://github.com/avalonmediasystem/browse-everything.git", tag: 'v1.2.0-avalon' +gem 'browse-everything', git: "https://github.com/avalonmediasystem/browse-everything.git", branch: 'v1.2-avalon' gem 'fastimage' gem 'media_element_add_to_playlist', git: 'https://github.com/avalonmediasystem/media-element-add-to-playlist.git', tag: 'avalon-r6.5' gem 'mediainfo', git: "https://github.com/avalonmediasystem/mediainfo.git", tag: 'v0.7.1-avalon' diff --git a/Gemfile.lock b/Gemfile.lock index 49a1818912..f344d67f38 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -24,8 +24,8 @@ GIT GIT remote: https://github.com/avalonmediasystem/browse-everything.git - revision: 38610d19d36105ca9c311e0a641fdb43697fabea - tag: v1.2.0-avalon + revision: fb3060bf2a4e556b6cbf84d7ac9a363f8ac20583 + branch: v1.2-avalon specs: browse-everything (1.2.0) addressable (~> 2.5) @@ -199,13 +199,13 @@ GEM autoprefixer-rails (10.4.7.0) execjs (~> 2) aws-eventstream (1.2.0) - aws-partitions (1.709.0) + aws-partitions (1.735.0) aws-record (2.10.1) aws-sdk-dynamodb (~> 1.18) aws-sdk-cloudfront (1.75.0) aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-core (3.170.0) + aws-sdk-core (3.171.0) aws-eventstream (~> 1, >= 1.0.2) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.5) @@ -216,7 +216,7 @@ GEM aws-sdk-elastictranscoder (1.40.0) aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-kms (1.62.0) + aws-sdk-kms (1.63.0) aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) aws-sdk-rails (3.7.0) @@ -227,7 +227,7 @@ GEM aws-sessionstore-dynamodb (~> 2) concurrent-ruby (~> 1) railties (>= 5.2.0) - aws-sdk-s3 (1.119.0) + aws-sdk-s3 (1.119.2) aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) @@ -459,7 +459,7 @@ GEM webrick google-apis-drive_v3 (0.37.0) google-apis-core (>= 0.11.0, < 2.a) - googleauth (1.3.0) + googleauth (1.5.0) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) @@ -661,14 +661,14 @@ GEM nio4r (~> 2.0) raabro (1.4.0) racc (1.6.2) - rack (2.2.6.3) + rack (2.2.6.4) rack-cors (1.1.1) rack (>= 2.0.0) rack-protection (3.0.5) rack rack-proxy (0.7.6) rack - rack-test (2.0.2) + rack-test (2.1.0) rack (>= 1.3) rails (7.0.4.2) actioncable (= 7.0.4.2) From 58f8eb183d72d7bdd48789611e8dbab76c8dafa5 Mon Sep 17 00:00:00 2001 From: Chris Colvard Date: Mon, 27 Mar 2023 17:01:06 -0400 Subject: [PATCH 05/14] Bump BE again --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index f344d67f38..55b49f5128 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -24,7 +24,7 @@ GIT GIT remote: https://github.com/avalonmediasystem/browse-everything.git - revision: fb3060bf2a4e556b6cbf84d7ac9a363f8ac20583 + revision: 51ac41d1631eba86b123222d9bfeef342f25ec56 branch: v1.2-avalon specs: browse-everything (1.2.0) From 077dae1d7180ae9420b42e67e8f5b4ae9e576052 Mon Sep 17 00:00:00 2001 From: dananji Date: Mon, 27 Mar 2023 14:21:59 -0700 Subject: [PATCH 06/14] Fix player controls getting hidden while scrubbing --- .../mediaelement/mediaelement-and-player.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/vendor/assets/javascripts/mediaelement/mediaelement-and-player.js b/vendor/assets/javascripts/mediaelement/mediaelement-and-player.js index 947179759f..6c50d1033f 100644 --- a/vendor/assets/javascripts/mediaelement/mediaelement-and-player.js +++ b/vendor/assets/javascripts/mediaelement/mediaelement-and-player.js @@ -1936,7 +1936,15 @@ Object.assign(_player2.default.prototype, { } if (t.forcedHandlePause) { t.slider.focus(); - t.play(); + let playPromise = t.play(); + if(playPromise !== undefined) { + playPromise.then(_ => { + // Show play UI, and enable controls + t.play(); + t.enableControls(); + }) + .catch(error => { }) + } } t.forcedHandlePause = false; }; From 79fd914c908f7107c141562ebfd1f75670d7f336 Mon Sep 17 00:00:00 2001 From: dananji Date: Mon, 27 Mar 2023 16:35:38 -0700 Subject: [PATCH 07/14] Fix player toolbar icons in Android when auto advancing to next section --- .../avalon_player_new.es6 | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 b/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 index cbe8da7244..5fd4425fae 100644 --- a/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 +++ b/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 @@ -280,7 +280,7 @@ class MEJSPlayer { ); // Build playlists button from the new stream when not in playlists - if(!playlistItemsT) { + if(!playlistItemsT && !this.mejsUtility.isMobile()) { this.player.options.playlistItemDefaultTitle = this.currentStreamInfo.embed_title; this.player.buildaddToPlaylist(this.player, null, null, null); } @@ -290,11 +290,20 @@ class MEJSPlayer { this.player.buildplaylistItems(this.player, null, null, this.mediaElement); } - // Set defaultQuality in player options before building the quality feature - this.player.options.defaultQuality = this.localStorage.getItem('quality'); + // Quality selector is turned off in mobile devices + if(!mejs.Features.isAndroid) { + // Set defaultQuality in player options before building the quality feature + this.player.options.defaultQuality = this.localStorage.getItem('quality'); - // Build quality - this.player.buildquality(this.player, null, null, this.mediaElement); + // Build quality + this.player.buildquality(this.player, null, null, this.mediaElement); + } else { + // Set current source in absence of the quality selection + let currentSource = this.currentStreamInfo.stream_hls + .filter(src => src.quality == this.player.options.defaultQuality)[0]; + + this.player.setSrc(currentSource.url); + } // Set startVolume in options from the current mediaelement instance this.player.options.startVolume = this.mediaElement.volume; @@ -454,7 +463,7 @@ class MEJSPlayer { * @return {void} */ handleError(error, mediaElement, originalNode) { - console.log('MEJS CREATE ERROR: ' + error); + console.log('MEJS ERROR: ' + error); } /** * MediaElement render success callback function From 58ca0cda6b6e5868cbaec7024da1c844d45076ed Mon Sep 17 00:00:00 2001 From: Chris Colvard Date: Tue, 28 Mar 2023 13:56:03 -0400 Subject: [PATCH 08/14] Pull in ActiveEncode patch version to fix google drive browse-everything case --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 3c222bf03a..cc3f88dec3 100644 --- a/Gemfile +++ b/Gemfile @@ -74,7 +74,7 @@ gem 'omniauth-lti', git: "https://github.com/avalonmediasystem/omniauth-lti.git" gem "omniauth-saml", "~> 2.0" # Media Access & Transcoding -gem 'active_encode', '~> 1.0', '>= 1.1.2' +gem 'active_encode', '~> 1.0', '>= 1.1.3' gem 'audio_waveform-ruby', '~> 1.0.7', require: 'audio_waveform' gem 'browse-everything', git: "https://github.com/avalonmediasystem/browse-everything.git", branch: 'v1.2-avalon' gem 'fastimage' diff --git a/Gemfile.lock b/Gemfile.lock index 55b49f5128..80042a49a2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -143,7 +143,7 @@ GEM active_elastic_job (3.2.0) aws-sdk-sqs (~> 1) rails (>= 5.2.6, < 7.1) - active_encode (1.1.2) + active_encode (1.1.3) addressable (~> 2.8) rails active_fedora-datastreams (0.5.0) @@ -993,7 +993,7 @@ DEPENDENCIES active-fedora (~> 14.0, >= 14.0.1) active_annotations (~> 0.4) active_elastic_job - active_encode (~> 1.0, >= 1.1.2) + active_encode (~> 1.0, >= 1.1.3) active_fedora-datastreams (~> 0.5) activejob-traffic_control activejob-uniqueness From 83a67256875acd3db5a7b7439322241003fbb2c4 Mon Sep 17 00:00:00 2001 From: dananji Date: Tue, 28 Mar 2023 10:58:50 -0700 Subject: [PATCH 09/14] Display correct captions for auto advancing video sections in mobile devices --- .../media_player_wrapper/avalon_player_new.es6 | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 b/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 index 5fd4425fae..5615aa5a9e 100644 --- a/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 +++ b/app/assets/javascripts/media_player_wrapper/avalon_player_new.es6 @@ -300,7 +300,7 @@ class MEJSPlayer { } else { // Set current source in absence of the quality selection let currentSource = this.currentStreamInfo.stream_hls - .filter(src => src.quality == this.player.options.defaultQuality)[0]; + .filter(src => src.quality === this.player.options.defaultQuality)[0]; this.player.setSrc(currentSource.url); } @@ -323,8 +323,15 @@ class MEJSPlayer { */ reInitializeCaptions() { if (this.currentStreamInfo.captions_path) { - // Place tracks button after volume button when tracks are available - this.player.featurePosition.tracks = this.player.featurePosition.volume + 1; + // Place tracks button + if(this.mejsUtility.isMobile()) { + // after trackScrubber button in mobile devices + this.player.featurePosition.tracks = this.player.featurePosition.trackScrubber + 1; + } else { + // after volume button in desktop devices + this.player.featurePosition.tracks = this.player.featurePosition.volume + 1; + } + this.player.buildtracks(this.player, null, this.player.layers, this.mediaElement); // Turn on captions this.toggleCaptions(); From afb4a9ef22f73facb952df18956d9eed6f46e817 Mon Sep 17 00:00:00 2001 From: dananji Date: Tue, 28 Mar 2023 12:56:10 -0700 Subject: [PATCH 10/14] Fix for video player aspect ratio change when switching between sections --- .../javascripts/media_player_wrapper/mejs4_helper_utility.es6 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/media_player_wrapper/mejs4_helper_utility.es6 b/app/assets/javascripts/media_player_wrapper/mejs4_helper_utility.es6 index ecbfbb4abc..dfba22c634 100644 --- a/app/assets/javascripts/media_player_wrapper/mejs4_helper_utility.es6 +++ b/app/assets/javascripts/media_player_wrapper/mejs4_helper_utility.es6 @@ -30,8 +30,8 @@ class MEJSUtility { node = document.createElement('video'); node.setAttribute('id', 'mejs-avalon-player'); node.setAttribute('controls', ''); - node.setAttribute('width', '450'); - node.setAttribute('height', '309'); + node.setAttribute('width', '480'); + node.setAttribute('height', '270'); node.setAttribute('style', 'width: 100%; height: 100%'); if (currentStreamInfo.poster_image) { node.setAttribute('poster', currentStreamInfo.poster_image); From f76387444e35b069cb7de8d785d67a3af6c75d36 Mon Sep 17 00:00:00 2001 From: dananji Date: Thu, 30 Mar 2023 13:26:01 -0700 Subject: [PATCH 11/14] Fix flashing error message in player when scrubbing --- .../mediaelement/mediaelement-and-player.js | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/vendor/assets/javascripts/mediaelement/mediaelement-and-player.js b/vendor/assets/javascripts/mediaelement/mediaelement-and-player.js index 6c50d1033f..2ad33e56fc 100644 --- a/vendor/assets/javascripts/mediaelement/mediaelement-and-player.js +++ b/vendor/assets/javascripts/mediaelement/mediaelement-and-player.js @@ -1936,15 +1936,17 @@ Object.assign(_player2.default.prototype, { } if (t.forcedHandlePause) { t.slider.focus(); - let playPromise = t.play(); - if(playPromise !== undefined) { - playPromise.then(_ => { - // Show play UI, and enable controls - t.play(); - t.enableControls(); - }) - .catch(error => { }) - } + setTimeout(function () { + let playPromise = t.play(); + if(playPromise !== undefined) { + playPromise.then(_ => { + // Show play UI, and enable controls + t.play(); + t.enableControls(); + }) + .catch(error => { }) + } + }, 150) } t.forcedHandlePause = false; }; From 9a9540d21fa2cbdd6c1c1464e48fe7b5229b524b Mon Sep 17 00:00:00 2001 From: Chris Colvard Date: Fri, 31 Mar 2023 12:59:26 -0400 Subject: [PATCH 12/14] Remove special handling of childless divs --- app/models/iiif_canvas_presenter.rb | 12 ----------- spec/models/iiif_canvas_presenter_spec.rb | 26 ----------------------- 2 files changed, 38 deletions(-) diff --git a/app/models/iiif_canvas_presenter.rb b/app/models/iiif_canvas_presenter.rb index df3b127331..9325d24626 100644 --- a/app/models/iiif_canvas_presenter.rb +++ b/app/models/iiif_canvas_presenter.rb @@ -94,14 +94,6 @@ def simple_iiif_range(label = stream_info[:embed_title]) end def structure_to_iiif_range - # Remove all "Div" nodes which do not have a "Span" descendant to ensure a valid manifest. - # According the to IIIF presentation 3 spec each Range needs to have a descendant that is a Canvas. - # See https://iiif.io/api/presentation/3.0/#34-structural-properties - structure_ng_xml.root.xpath("//*[local-name() = 'Div' and not(descendant::*[local-name() = 'Span'])]").map(&:remove) - - # Return default range if nothing valid is left - return simple_iiif_range(structure_ng_xml.root.attr('label')) if structure_ng_xml.root.children.all?(&:blank?) - div_to_iiif_range(structure_ng_xml.root) end @@ -114,10 +106,6 @@ def div_to_iiif_range(div_node) end end - # if a non-leaf node has no valid "Div" or "Span" children, then it would become empty range node containing no canvas - # raise an exception here as this error shall have been caught and handled by the parser and shall never happen here - raise Nokogiri::XML::SyntaxError, "Empty root or Div node: #{div_node[:label]}" if items.empty? - IiifManifestRange.new( label: { "none" => [div_node[:label]] }, items: items diff --git a/spec/models/iiif_canvas_presenter_spec.rb b/spec/models/iiif_canvas_presenter_spec.rb index d21ba0953d..f12563be45 100644 --- a/spec/models/iiif_canvas_presenter_spec.rb +++ b/spec/models/iiif_canvas_presenter_spec.rb @@ -87,31 +87,5 @@ expect(subject.items.first.media_fragment).to eq 't=0,' end end - - context 'with invalid structural metadata' do - let(:structure_xml) { '
' } - - it 'removes ranges without descendant canvases' do - expect(subject.label.to_s).to eq '{"none"=>["Test"]}' - expect(subject.items.size).to eq 1 - expect(subject.items.first.label.to_s).to eq '{"none"=>["Div 1"]}' - expect(subject.items.first.items.size).to eq 1 - expect(subject.items.first.items.first.label.to_s).to eq '{"none"=>["Span 1"]}' - expect(subject.items.first.items.first.items.size).to eq 1 - expect(subject.items.first.items.first.items.first).to be_a IiifCanvasPresenter - expect(subject.items.first.items.first.items.first.media_fragment).to eq 't=0.0,1.235' - end - - context 'when there are no valid ranges' do - let(:structure_xml) { '
' } - - it 'autogenerates a basic range but preserves the root level label' do - expect(subject.label.to_s).to eq '{"none"=>["Test"]}' - expect(subject.items.size).to eq 1 - expect(subject.items.first).to be_a IiifCanvasPresenter - expect(subject.items.first.media_fragment).to eq 't=0,' - end - end - end end end From d28edd6c8671895f85712797f198df58d24c2d06 Mon Sep 17 00:00:00 2001 From: Chris Colvard Date: Fri, 31 Mar 2023 10:46:16 -0400 Subject: [PATCH 13/14] Override ActiveFedora and HydraAccessControls to ensure AccessControl objects are marked dirty and autosave so they get indexed properly --- config/initializers/active_fedora_general.rb | 57 ++++++++++++++++++++ spec/jobs/bulk_action_job_spec.rb | 6 +++ spec/models/media_object_spec.rb | 30 +++++++++++ 3 files changed, 93 insertions(+) diff --git a/config/initializers/active_fedora_general.rb b/config/initializers/active_fedora_general.rb index 933d8aed38..17bbe1408f 100644 --- a/config/initializers/active_fedora_general.rb +++ b/config/initializers/active_fedora_general.rb @@ -34,3 +34,60 @@ def content_disposition_filename ::RDF::URI.decode(filename) if filename end end + +# Overrides that ensure AccessControl objects are marked dirty when read/edit/discover groups/users are changed and autosave if dirty +# This fixes a timing bug where AccessControl objects are saved in an after_save callback which runs after normal indexing occurs +# See https://github.com/avalonmediasystem/avalon/issues/5140 + +# Override contained_rdf_sources to ensure AccessControl objects get autosaved when dirty +ActiveFedora::Base.class_eval do + private + def save_contained_resources + contained_resources.changed.each do |_, resource| + resource.save + end + save_access_control_resources + end + + def save_access_control_resources + access_control_sources.changed.each do |_, resource| + resource.save + end + end + + def access_control_sources + @access_control_sources ||= ActiveFedora::AssociationHash.new(self, access_control_reflections) + end + + def access_control_reflections + self.class.reflect_on_all_associations(:belongs_to).select { |_, reflection| reflection.klass <= Hydra::AccessControl } + end +end + +# Enable dirty tracking for the permissions attribute +Rails.application.config.to_prepare do + Hydra::AccessControl.define_attribute_methods :permissions +end + +# Override set_entities to notify ActiveModel::Dirty dirty tracking that the permissions attribute is changing +Hydra::AccessControls::Permissions.module_eval do + private + # @param [Symbol] permission either :discover, :read or :edit + # @param [Symbol] type either :person or :group + # @param [Array] values Values to set + # @param [Array] changeable Values we are allowed to change + def set_entities(permission, type, values, changeable) + (changeable - values).each do |entity| + for_destroy = search_by_type_and_mode(type, permission_to_uri(permission)).select { |p| p.agent_name == entity } + access_control.permissions_will_change! + permissions.delete(for_destroy) + end + + values.each do |agent_name| + exists = search_by_type_and_mode(type, permission_to_uri(permission)).select { |p| p.agent_name == agent_name } + access_control.permissions_will_change! + permissions.build(name: agent_name, access: permission.to_s, type: type) unless exists.present? + end + end +end +# End of overrides for AccessControl dirty tracking and autosaving diff --git a/spec/jobs/bulk_action_job_spec.rb b/spec/jobs/bulk_action_job_spec.rb index d54309019f..1b8609021d 100644 --- a/spec/jobs/bulk_action_job_spec.rb +++ b/spec/jobs/bulk_action_job_spec.rb @@ -122,6 +122,9 @@ def check_push(result) mo.reload expect(mo.read_users).to contain_exactly("co_user") expect(mo.read_groups).to contain_exactly("co_group", "public") + solr_doc = ActiveFedora::SolrService.query("id:#{mo.id}").first + expect(solr_doc["read_access_person_ssim"]).to contain_exactly("co_user") + expect(solr_doc["read_access_group_ssim"]).to contain_exactly("co_group", "public") end end @@ -131,6 +134,9 @@ def check_push(result) mo.reload expect(mo.read_users).to contain_exactly("mo_user", "co_user") expect(mo.read_groups).to contain_exactly("mo_group", "co_group", "public") + solr_doc = ActiveFedora::SolrService.query("id:#{mo.id}").first + expect(solr_doc["read_access_person_ssim"]).to contain_exactly("mo_user", "co_user") + expect(solr_doc["read_access_group_ssim"]).to contain_exactly("mo_group", "co_group", "public") end end end diff --git a/spec/models/media_object_spec.rb b/spec/models/media_object_spec.rb index 6825aa285c..238b1b32b5 100644 --- a/spec/models/media_object_spec.rb +++ b/spec/models/media_object_spec.rb @@ -1062,4 +1062,34 @@ end end end + + describe 'read_groups=' do + let(:solr_doc) { ActiveFedora::SolrService.query("id:#{media_object.id}").first } + + context 'when creating a MediaObject' do + let(:media_object) { FactoryBot.build(:media_object) } + + it 'saves and indexes' do + expect(media_object.read_groups).to be_empty + media_object.read_groups = ["ExternalGroup"] + expect(media_object.access_control).to be_changed + media_object.save + expect(media_object.reload.read_groups).to eq ["ExternalGroup"] + expect(solr_doc["read_access_group_ssim"]).to eq ["ExternalGroup"] + end + end + + context 'when updating a MediaObject' do + let(:media_object) { FactoryBot.create(:media_object) } + + it 'saves and indexes' do + expect(media_object.read_groups).to be_empty + media_object.read_groups = ["ExternalGroup"] + expect(media_object.access_control).to be_changed + media_object.save + expect(media_object.reload.read_groups).to eq ["ExternalGroup"] + expect(solr_doc["read_access_group_ssim"]).to eq ["ExternalGroup"] + end + end + end end From 949c4ca3661765d5c12c90fdf38572e9a0f19463 Mon Sep 17 00:00:00 2001 From: Chris Colvard Date: Fri, 31 Mar 2023 14:54:58 -0400 Subject: [PATCH 14/14] Bump rails version for latest security patch --- Gemfile | 2 +- Gemfile.lock | 108 +++++++++++++++++++++++++-------------------------- 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/Gemfile b/Gemfile index cc3f88dec3..a6733c68bb 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ gem 'bootsnap', require: false gem 'listen' gem 'net-smtp', require: false gem 'psych', '< 4' -gem 'rails', '=7.0.4.2' +gem 'rails', '=7.0.4.3' gem 'sprockets', '~>3.7.2' #gem 'sprockets-rails', require: 'sprockets/railtie' gem 'sqlite3' diff --git a/Gemfile.lock b/Gemfile.lock index 80042a49a2..271d12d1db 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,47 +76,47 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.0.4.2) - actionpack (= 7.0.4.2) - activesupport (= 7.0.4.2) + actioncable (7.0.4.3) + actionpack (= 7.0.4.3) + activesupport (= 7.0.4.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.4.2) - actionpack (= 7.0.4.2) - activejob (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionmailbox (7.0.4.3) + actionpack (= 7.0.4.3) + activejob (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.4.2) - actionpack (= 7.0.4.2) - actionview (= 7.0.4.2) - activejob (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionmailer (7.0.4.3) + actionpack (= 7.0.4.3) + actionview (= 7.0.4.3) + activejob (= 7.0.4.3) + activesupport (= 7.0.4.3) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.4.2) - actionview (= 7.0.4.2) - activesupport (= 7.0.4.2) + actionpack (7.0.4.3) + actionview (= 7.0.4.3) + activesupport (= 7.0.4.3) rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.4.2) - actionpack (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + actiontext (7.0.4.3) + actionpack (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.4.2) - activesupport (= 7.0.4.2) + actionview (7.0.4.3) + activesupport (= 7.0.4.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -153,8 +153,8 @@ GEM om (~> 3.1) rdf (~> 3.2) rdf-rdfxml (~> 3.2) - activejob (7.0.4.2) - activesupport (= 7.0.4.2) + activejob (7.0.4.3) + activesupport (= 7.0.4.3) globalid (>= 0.3.6) activejob-traffic_control (0.1.3) activejob (>= 4.2) @@ -163,25 +163,25 @@ GEM activejob-uniqueness (0.2.5) activejob (>= 4.2, < 7.1) redlock (>= 1.2, < 2) - activemodel (7.0.4.2) - activesupport (= 7.0.4.2) - activerecord (7.0.4.2) - activemodel (= 7.0.4.2) - activesupport (= 7.0.4.2) + activemodel (7.0.4.3) + activesupport (= 7.0.4.3) + activerecord (7.0.4.3) + activemodel (= 7.0.4.3) + activesupport (= 7.0.4.3) activerecord-session_store (2.0.0) actionpack (>= 5.2.4.1) activerecord (>= 5.2.4.1) multi_json (~> 1.11, >= 1.11.2) rack (>= 2.0.8, < 3) railties (>= 5.2.4.1) - activestorage (7.0.4.2) - actionpack (= 7.0.4.2) - activejob (= 7.0.4.2) - activerecord (= 7.0.4.2) - activesupport (= 7.0.4.2) + activestorage (7.0.4.3) + actionpack (= 7.0.4.3) + activejob (= 7.0.4.3) + activerecord (= 7.0.4.3) + activesupport (= 7.0.4.3) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.4.2) + activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -670,20 +670,20 @@ GEM rack rack-test (2.1.0) rack (>= 1.3) - rails (7.0.4.2) - actioncable (= 7.0.4.2) - actionmailbox (= 7.0.4.2) - actionmailer (= 7.0.4.2) - actionpack (= 7.0.4.2) - actiontext (= 7.0.4.2) - actionview (= 7.0.4.2) - activejob (= 7.0.4.2) - activemodel (= 7.0.4.2) - activerecord (= 7.0.4.2) - activestorage (= 7.0.4.2) - activesupport (= 7.0.4.2) + rails (7.0.4.3) + actioncable (= 7.0.4.3) + actionmailbox (= 7.0.4.3) + actionmailer (= 7.0.4.3) + actionpack (= 7.0.4.3) + actiontext (= 7.0.4.3) + actionview (= 7.0.4.3) + activejob (= 7.0.4.3) + activemodel (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) bundler (>= 1.15.0) - railties (= 7.0.4.2) + railties (= 7.0.4.3) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -696,9 +696,9 @@ GEM rails_same_site_cookie (0.1.9) rack (>= 1.5) user_agent_parser (~> 2.6) - railties (7.0.4.2) - actionpack (= 7.0.4.2) - activesupport (= 7.0.4.2) + railties (7.0.4.3) + actionpack (= 7.0.4.3) + activesupport (= 7.0.4.3) method_source rake (>= 12.2) thor (~> 1.0) @@ -1079,7 +1079,7 @@ DEPENDENCIES psych (< 4) puma (>= 4.3.8) rack-cors - rails (= 7.0.4.2) + rails (= 7.0.4.3) rails-controller-testing rails_same_site_cookie rb-readline