Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions app/controllers/master_files_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -243,11 +243,8 @@ def hls_manifest
quality = params[:quality]
if request.head?
auth_token = request.headers['Authorization']&.sub('Bearer ', '')
if StreamToken.valid_token?(auth_token, @master_file.id) || can?(:read, @master_file)
return head :ok
else
return head :unauthorized
end
return iiif_auth_probe_resp(success: false) unless StreamToken.valid_token?(auth_token, @master_file.id) || can?(:read, @master_file)
iiif_auth_probe_resp(success: true)
else
return head :unauthorized if cannot?(:read, @master_file)
@hls_streams = if quality == "auto"
Expand Down Expand Up @@ -283,16 +280,25 @@ def delete_structure

def iiif_auth_token
if cannot? :read, @master_file
head :unauthorized
render 'iiif_auth_token_error', layout: false, locals: { message_id: message_id }
else
message_id = params[:messageId]
origin = params[:origin]
access_token = StreamToken.find_or_create_session_token(session, @master_file.id)
expires = (StreamToken.find_by(token: access_token).expires - Time.now.utc).to_i
render 'iiif_auth_token', layout: false, locals: { message_id: message_id, origin: origin, access_token: access_token, expires: expires }
end
end

def iiif_auth_probe_resp(success: false)
{
"@context": "http://iiif.io/api/auth/2/context.json",
"type": "AuthProbeResult2",
"status": success ? 200 : 403,
"header": success ? { "en": [I18n.t('iiif.auth.failureHeader')] } : nil,
"note": success ? { "en": [I18n.t('iiif.auth.failureDescription')] } : nil
}.compact
end

def move
current_media_object = @master_file.media_object
authorize! :update, current_media_object
Expand Down
49 changes: 25 additions & 24 deletions app/models/iiif_canvas_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -287,32 +287,33 @@ def structure_ng_xml

def auth_service(quality)
{
"context": "http://iiif.io/api/auth/1/context.json",
"@id": Rails.application.routes.url_helpers.new_user_session_url(login_popup: 1),
"@type": "AuthCookieService1",
"confirmLabel": I18n.t('iiif.auth.confirmLabel'),
"description": I18n.t('iiif.auth.description'),
"failureDescription": I18n.t('iiif.auth.failureDescription'),
"failureHeader": I18n.t('iiif.auth.failureHeader'),
"header": I18n.t('iiif.auth.header'),
"label": I18n.t('iiif.auth.label'),
"profile": "http://iiif.io/api/auth/1/login",
"id": Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality),
"type": "AuthProbeService2",
"errorNote": { "en": [I18n.t('iiif.auth.failureDescription')] },
"errorHeading": { "en": [I18n.t('iiif.auth.failureHeader')] },
"service": [
{
"@id": Rails.application.routes.url_helpers.hls_manifest_master_file_url(master_file.id, quality: quality),
"@type": "AuthProbeService1",
"profile": "http://iiif.io/api/auth/1/probe"
},
{
"@id": Rails.application.routes.url_helpers.iiif_auth_token_url(id: master_file.id),
"@type": "AuthTokenService1",
"profile": "http://iiif.io/api/auth/1/token"
},
{
"@id": Rails.application.routes.url_helpers.destroy_user_session_url,
"@type": "AuthLogoutService1",
"label": I18n.t('iiif.auth.logoutLabel'),
"profile": "http://iiif.io/api/auth/1/logout"
"id": Rails.application.routes.url_helpers.new_user_session_url(login_popup: 1),
"type": "AuthAccessService2",
"confirmLabel": { "en": [I18n.t('iiif.auth.confirmLabel')] },
"note": { "en": [I18n.t('iiif.auth.description')] },
"heading": { "en": [I18n.t('iiif.auth.header')] },
"label": { "en": [I18n.t('iiif.auth.label')] },
"profile": "active",
"service": [
{
"id": Rails.application.routes.url_helpers.iiif_auth_token_url(id: master_file.id),
"type": "AuthAccessTokenService2",
"profile": "http://iiif.io/api/auth/1/token",
"errorNote": { "en": [I18n.t('iiif.auth.failureDescription')] },
"errorHeading": { "en": [I18n.t('iiif.auth.failureHeader')] }
},
{
"id": Rails.application.routes.url_helpers.destroy_user_session_url,
"type": "AuthLogoutService2",
"label": { "en": [I18n.t('iiif.auth.logoutLabel')] }
}
]
}
]
}
Expand Down
8 changes: 7 additions & 1 deletion app/views/master_files/iiif_auth_token.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ Unless required by applicable law or agreed to in writing, software distributed
<body>
<script>
window.parent.postMessage(
{"expiresIn": <%= expires %>, "accessToken": "<%= access_token %>", "messageId": "<%= message_id %>"},
{
"@context": "http://iiif.io/api/auth/2/context.json",
"type": "AuthAccessToken2",
"accessToken": "<%= access_token %>",
"expiresIn": <%= expires %>,
"messageId": "<%= message_id %>"
},
"<%= origin %>"
);
</script>
Expand Down
30 changes: 30 additions & 0 deletions app/views/master_files/iiif_auth_token_error.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<%#
Copyright 2011-2025, The Trustees of Indiana University and Northwestern
University. Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
--- END LICENSE_HEADER BLOCK ---
%>
<html>
<body>
<script>
window.parent.postMessage(
{
"@context": "http://iiif.io/api/auth/2/context.json",
"type": "AuthAccessTokenError2",
"profile": "missingAspect",
"heading": { "en": ["<%= I18n.t('iiif.auth.failureHeader') %>"]},
"messageId": "<%= message_id %>"
}
);
</script>
</body>
</html>