sufia 3.2.1 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/CONTRIBUTING.md +2 -0
- data/Gemfile +5 -0
- data/History.md +17 -0
- data/README.md +6 -6
- data/SUFIA_VERSION +1 -1
- data/app/controllers/mailbox_controller.rb +1 -2
- data/app/controllers/single_use_links_controller.rb +40 -0
- data/app/controllers/single_use_links_viewer_controller.rb +73 -0
- data/app/views/single_use_links/new_download.html.erb +5 -0
- data/app/views/{single_use_link/generate_show.html.erb → single_use_links/new_show.html.erb} +3 -1
- data/app/views/{single_use_link → single_use_links_viewer}/show.html.erb +2 -2
- data/config/routes.rb +4 -4
- data/lib/sufia/version.rb +1 -1
- data/spec/controllers/single_use_links_controller_spec.rb +69 -0
- data/spec/controllers/{single_use_link_controller_spec.rb → single_use_links_viewer_controller_spec.rb} +28 -59
- data/spec/features/single_use_links_spec.rb +38 -0
- data/spec/models/single_use_link_spec.rb +19 -18
- data/spec/support/lib/generators/test_app_generator.rb +0 -12
- data/sufia-models/app/models/domain_term.rb +5 -1
- data/sufia-models/app/models/local_authority.rb +10 -4
- data/sufia-models/app/models/single_use_link.rb +35 -16
- data/sufia-models/lib/sufia/models/version.rb +1 -1
- data/sufia-models/sufia-models.gemspec +1 -1
- data/sufia.gemspec +1 -1
- data/tasks/release.rake +1 -2
- metadata +23 -11
- data/app/controllers/single_use_link_controller.rb +0 -95
- data/app/views/single_use_link/generate_download.html.erb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 192f05ee63c1448500374b381283f9796bb6a864
|
4
|
+
data.tar.gz: 5017ed019cf96dd363991d15718c48599ae10fcb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00027897e9f28c13ece3f1413db477941479cb2f0bebb10b90e6ebb1c73d6834866a0aecb219fbdf9d31ceea73decaacb2028805de3d5846661256a7ac3c7966
|
7
|
+
data.tar.gz: c40470550b3593473d5bfb75caea483477d1640d8a76eeecb0f0060d4341768f251184663f02c81d8f22ad9b320b218cbfad5e241a5a7b0fa670c7db07f1e9a5
|
data/.travis.yml
CHANGED
data/CONTRIBUTING.md
CHANGED
@@ -78,6 +78,8 @@ You should also add yourself to the `CONTRIBUTORS.md` file in the root of the pr
|
|
78
78
|
|
79
79
|
### Submitting Changes
|
80
80
|
|
81
|
+
[Detailed Walkthrough of One Pull Request per Commit](http://ndlib.github.io/practices/one-commit-per-pull-request/)
|
82
|
+
|
81
83
|
* Read the article ["Using Pull Requests"](https://help.github.com/articles/using-pull-requests) on GitHub.
|
82
84
|
* Make sure your branch is up to date with its parent branch (i.e. master)
|
83
85
|
* `git checkout master`
|
data/Gemfile
CHANGED
@@ -19,5 +19,10 @@ group :development, :test do
|
|
19
19
|
gem 'bcrypt-ruby'
|
20
20
|
gem "jettywrapper"
|
21
21
|
gem "factory_girl_rails", "~> 4.2.1"
|
22
|
+
gem "devise"
|
23
|
+
gem 'jquery-rails'
|
24
|
+
gem 'sass-rails'
|
25
|
+
gem 'turbolinks'
|
26
|
+
gem "bootstrap-sass"
|
22
27
|
gem "simplecov", :require => false
|
23
28
|
end # (leave this comment here to catch a stray line inserted by blacklight!)
|
data/History.md
CHANGED
@@ -1,5 +1,22 @@
|
|
1
1
|
# History of Sufia releases
|
2
2
|
|
3
|
+
## 3.3.0
|
4
|
+
* Fix authorities deprecations [Justin Coyne]
|
5
|
+
* Fix deprecation on MailboxController [Justin Coyne]
|
6
|
+
* blacklight 4.4.1/0 doesn't work with kaminari > 0.14.1 See projectblacklight/blacklight#614 [Justin Coyne]
|
7
|
+
* Allow acts_as_follower to be 0.2.0 for Rails 4 support [Justin Coyne]
|
8
|
+
* Don't run blacklight and hydra generator twice [Justin Coyne]
|
9
|
+
* Remove deprecation warning on Rails 4 [Justin Coyne]
|
10
|
+
* Updating CONTRIBUTING.md as per Hydra v6.0.0 [Jeremy Friesen]
|
11
|
+
* use cancan to authorize and validate single-use tokens. [Chris Beer]
|
12
|
+
* Add ImageMagick as a software requirement in the README. [Jessie Keck]
|
13
|
+
* split SingleUseLinkController into the authenticated controller that creates links, and a viewer that handles retrieving content for token-bearing users [Chris Beer]
|
14
|
+
* remove explicit GenericFile references, and replace them with Rails magic [Chris Beer]
|
15
|
+
* Refactor single-use links for style and clarity [Chris Beer]
|
16
|
+
* add more gems to the gemfile for running tests from the gem root [Chris Beer]
|
17
|
+
* add redis-server to the .travis.yml list of services [Chris Beer]
|
18
|
+
* Fix typos in README.md [Jessie Keck]
|
19
|
+
|
3
20
|
## 3.2.1
|
4
21
|
* Updating gemspec to not limit on sufia-models [Jeremy Friesen]
|
5
22
|
|
data/README.md
CHANGED
@@ -27,19 +27,19 @@ Sufia has the following features:
|
|
27
27
|
|
28
28
|
## Sufia needs the following software to work:
|
29
29
|
1. Solr
|
30
|
-
1. Fedora Commons
|
30
|
+
1. [Fedora Commons](http://www.fedora-commons.org/) digital repository
|
31
31
|
1. A SQL RDBMS (MySQL, SQLite)
|
32
32
|
1. [Redis](http://redis.io/) key-value store
|
33
|
+
1. [ImageMagick](http://www.imagemagick.org/)
|
33
34
|
1. Ruby
|
34
|
-
|
35
|
+
|
36
|
+
#### !! Ensure that you have all of the above components installed before you continue. !!
|
35
37
|
|
36
38
|
## Creating an application
|
37
39
|
### Generate base Rails install
|
38
40
|
```rails new my_app```
|
39
41
|
### Add gems to Gemfile
|
40
42
|
```
|
41
|
-
gem 'blacklight'
|
42
|
-
gem 'hydra-head'
|
43
43
|
gem 'sufia'
|
44
44
|
gem 'kaminari', github: 'harai/kaminari', branch: 'route_prefix_prototype' # required to handle pagination properly in dashboard. See https://github.com/amatsuda/kaminari/pull/322
|
45
45
|
gem 'jettywrapper'
|
@@ -53,7 +53,7 @@ Note the line with kaminari listed as a dependency. This is a temporary fix to
|
|
53
53
|
```
|
54
54
|
rails g blacklight --devise
|
55
55
|
rails g hydra:head -f
|
56
|
-
bundle install
|
56
|
+
bundle install
|
57
57
|
rails g sufia -f
|
58
58
|
rm public/index.html
|
59
59
|
```
|
@@ -116,7 +116,7 @@ resque-pool --daemon --environment development start
|
|
116
116
|
|
117
117
|
See https://github.com/defunkt/resque for more options
|
118
118
|
|
119
|
-
### If you want to enable transcoding of video,
|
119
|
+
### If you want to enable transcoding of video, install ffmpeg version 1.0+
|
120
120
|
#### On a mac
|
121
121
|
Use homebrew:
|
122
122
|
```
|
data/SUFIA_VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.3.0
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'sufia/single_use_error'
|
2
|
+
|
3
|
+
class SingleUseLinksController < ApplicationController
|
4
|
+
include Sufia::Noid
|
5
|
+
|
6
|
+
prepend_before_filter :normalize_identifier
|
7
|
+
before_filter :load_asset
|
8
|
+
before_filter :authenticate_user!
|
9
|
+
before_filter :authorize_user!
|
10
|
+
|
11
|
+
def new_download
|
12
|
+
@su = SingleUseLink.create :itemId => params[:id], :path => sufia.download_path(:id => @asset)
|
13
|
+
@link = sufia.download_single_use_link_path(@su.downloadKey)
|
14
|
+
|
15
|
+
respond_to do |format|
|
16
|
+
format.html
|
17
|
+
format.js { render :js => @link }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def new_show
|
22
|
+
@su = SingleUseLink.create :itemId => params[:id], :path => sufia.polymorphic_path(@asset)
|
23
|
+
@link = sufia.show_single_use_link_path(@su.downloadKey)
|
24
|
+
|
25
|
+
respond_to do |format|
|
26
|
+
format.html
|
27
|
+
format.js { render :js => @link }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
def authorize_user!
|
33
|
+
authorize! :read, @asset
|
34
|
+
end
|
35
|
+
|
36
|
+
def load_asset
|
37
|
+
@asset = ActiveFedora::Base.load_instance_from_solr(params[:id])
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'sufia/single_use_error'
|
2
|
+
|
3
|
+
class SingleUseLinksViewerController < ApplicationController
|
4
|
+
|
5
|
+
include Sufia::DownloadsControllerBehavior
|
6
|
+
|
7
|
+
skip_filter :normalize_identifier
|
8
|
+
skip_before_filter :load_datastream, :except => :download
|
9
|
+
|
10
|
+
before_filter :authorize_single_use_link!
|
11
|
+
|
12
|
+
class Ability
|
13
|
+
include CanCan::Ability
|
14
|
+
|
15
|
+
attr_reader :single_use_link
|
16
|
+
|
17
|
+
def initialize(user, single_use_link)
|
18
|
+
@user = user || User.new
|
19
|
+
|
20
|
+
@single_use_link = single_use_link
|
21
|
+
|
22
|
+
can :read, ActiveFedora::Base do |obj|
|
23
|
+
single_use_link.valid? and
|
24
|
+
single_use_link.itemId == obj.pid and single_use_link.destroy!
|
25
|
+
end if single_use_link
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
rescue_from Sufia::SingleUseError, :with => :render_single_use_error
|
31
|
+
rescue_from CanCan::AccessDenied, :with => :render_single_use_error
|
32
|
+
rescue_from ActiveRecord::RecordNotFound, :with => :render_single_use_error
|
33
|
+
|
34
|
+
|
35
|
+
def download
|
36
|
+
# send the data content
|
37
|
+
raise not_found_exception unless single_use_link.path == sufia.download_path(:id => @asset)
|
38
|
+
send_content(asset)
|
39
|
+
end
|
40
|
+
|
41
|
+
def show
|
42
|
+
raise not_found_exception unless single_use_link.path == sufia.polymorphic_path(@asset)
|
43
|
+
|
44
|
+
#show the file
|
45
|
+
@terms = @asset.terms_for_display
|
46
|
+
|
47
|
+
# create a dowload link that is single use for the user since we do not just want to show metadata we want to access it too
|
48
|
+
@su = single_use_link.create_for_path sufia.download_path(:id => @asset)
|
49
|
+
@download_link = sufia.download_single_use_link_path(@su.downloadKey)
|
50
|
+
end
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
def authorize_single_use_link!
|
55
|
+
authorize! :read, @asset
|
56
|
+
end
|
57
|
+
|
58
|
+
def single_use_link
|
59
|
+
@single_use_link ||= SingleUseLink.find_by_downloadKey! params[:id]
|
60
|
+
end
|
61
|
+
|
62
|
+
def not_found_exception
|
63
|
+
Sufia::SingleUseError.new('Single-Use Link Not Found')
|
64
|
+
end
|
65
|
+
|
66
|
+
def load_asset
|
67
|
+
@asset = ActiveFedora::Base.load_instance_from_solr(single_use_link.itemId)
|
68
|
+
end
|
69
|
+
|
70
|
+
def current_ability
|
71
|
+
@current_ability ||= SingleUseLinksViewerController::Ability.new current_user, single_use_link
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<div class="single-use-link">
|
2
|
+
<h1>Single Use Link</h1>
|
3
|
+
<p>Anyone can use the following link once to download the file</p>
|
4
|
+
<%= link_to @asset, @link, :class => 'download-link' %> <%= link_to raw('<i class="icon-link icon-large"></i>'), '#', :class => 'copypaste itemicon itemcode', :title => 'Copy File URL', :id => "copy_link_#{@asset.pid}" %>
|
5
|
+
</div>
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<div >
|
2
|
-
<h1 class="lower"><%= @
|
2
|
+
<h1 class="lower"><%= @asset %></h1>
|
3
3
|
<h2 class="non lower">Actions</h2>
|
4
4
|
<p>
|
5
5
|
<%= link_to "Download (can only be used once)", @download_link %>
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<table class="table table-striped"><!-- class="verticalheadings"> -->
|
11
11
|
<tbody>
|
12
12
|
<% @terms.each do |term| %>
|
13
|
-
<% vals = Array( @
|
13
|
+
<% vals = Array( @asset.send(term)) %>
|
14
14
|
<tr id='row_<%=term.to_s%>' class="expandable">
|
15
15
|
<th width="20%">
|
16
16
|
<%=get_label(term)%>
|
data/config/routes.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Sufia::Engine.routes.draw do
|
2
|
-
get 'single_use_link/generate_download/:id' => '
|
3
|
-
get 'single_use_link/generate_show/:id' => '
|
4
|
-
get 'single_use_link/show/:id' => '
|
5
|
-
get 'single_use_link/download/:id' => '
|
2
|
+
get 'single_use_link/generate_download/:id' => 'single_use_links#new_download', :as => :generate_download_single_use_link
|
3
|
+
get 'single_use_link/generate_show/:id' => 'single_use_links#new_show', :as => :generate_show_single_use_link
|
4
|
+
get 'single_use_link/show/:id' => 'single_use_links_viewer#show', :as => :show_single_use_link
|
5
|
+
get 'single_use_link/download/:id' => 'single_use_links_viewer#download', :as => :download_single_use_link
|
6
6
|
|
7
7
|
match 'batch_edits/clear' => 'batch_edits#clear', :as => :batch_edits_clear, via: [:get, :post]
|
8
8
|
|
data/lib/sufia/version.rb
CHANGED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SingleUseLinksController do
|
4
|
+
before(:all) do
|
5
|
+
@user = FactoryGirl.find_or_create(:user)
|
6
|
+
@file = GenericFile.new
|
7
|
+
@file.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
8
|
+
@file.apply_depositor_metadata(@user)
|
9
|
+
@file.save
|
10
|
+
@file2 = GenericFile.new
|
11
|
+
@file2.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
12
|
+
@file2.apply_depositor_metadata('mjg36')
|
13
|
+
@file2.save
|
14
|
+
end
|
15
|
+
after(:all) do
|
16
|
+
@file.delete
|
17
|
+
@file2.delete
|
18
|
+
SingleUseLink.delete_all
|
19
|
+
end
|
20
|
+
before do
|
21
|
+
controller.stub(:has_access?).and_return(true)
|
22
|
+
controller.stub(:clear_session_user) ## Don't clear out the authenticated session
|
23
|
+
end
|
24
|
+
describe "logged in user" do
|
25
|
+
before do
|
26
|
+
@user = FactoryGirl.find_or_create(:user)
|
27
|
+
sign_in @user
|
28
|
+
@now = DateTime.now
|
29
|
+
DateTime.stub(:now).and_return(@now)
|
30
|
+
@hash = "some-dummy-sha2-hash"
|
31
|
+
Digest::SHA2.should_receive(:new).and_return(@hash)
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "GET 'download'" do
|
35
|
+
it "and_return http success" do
|
36
|
+
get 'new_download', id:@file.pid
|
37
|
+
response.should be_success
|
38
|
+
assigns[:link].should == @routes.url_helpers.download_single_use_link_path(@hash)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "GET 'show'" do
|
44
|
+
it "and_return http success" do
|
45
|
+
get 'new_show', id:@file.pid
|
46
|
+
response.should be_success
|
47
|
+
assigns[:link].should == @routes.url_helpers.show_single_use_link_path(@hash)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "unkown user" do
|
54
|
+
describe "GET 'download'" do
|
55
|
+
it "and_return http failure" do
|
56
|
+
get 'new_download', id:@file.pid
|
57
|
+
response.should_not be_success
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "GET 'show'" do
|
62
|
+
it "and_return http failure" do
|
63
|
+
get 'new_show', id:@file.pid
|
64
|
+
response.should_not be_success
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe SingleUseLinksViewerController do
|
4
4
|
before(:all) do
|
5
5
|
@user = FactoryGirl.find_or_create(:user)
|
6
6
|
@file = GenericFile.new
|
@@ -13,65 +13,32 @@ describe SingleUseLinkController do
|
|
13
13
|
@file2.save
|
14
14
|
end
|
15
15
|
after(:all) do
|
16
|
-
SingleUseLink.delete_all
|
17
|
-
@user.delete
|
18
16
|
@file.delete
|
19
17
|
@file2.delete
|
18
|
+
SingleUseLink.delete_all
|
20
19
|
end
|
21
20
|
before do
|
22
21
|
controller.stub(:has_access?).and_return(true)
|
23
22
|
controller.stub(:clear_session_user) ## Don't clear out the authenticated session
|
24
23
|
end
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@now = DateTime.now
|
30
|
-
DateTime.stub(:now).and_return(@now)
|
31
|
-
@hash = "sha2hash"+@now.to_f.to_s
|
32
|
-
Digest::SHA2.should_receive(:new).and_return(@hash)
|
24
|
+
|
25
|
+
describe "retrieval links" do
|
26
|
+
let :show_link do
|
27
|
+
SingleUseLink.create itemId: @file.pid, path: Sufia::Engine.routes.url_helpers.generic_file_path(:id => @file)
|
33
28
|
end
|
34
|
-
|
35
|
-
|
36
|
-
SingleUseLink.
|
37
|
-
@user.delete
|
29
|
+
|
30
|
+
let :download_link do
|
31
|
+
SingleUseLink.create itemId: @file.pid, path: Sufia::Engine.routes.url_helpers.download_path(:id => @file)
|
38
32
|
end
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
response.should be_success
|
43
|
-
assigns[:link].should == @routes.url_helpers.download_single_use_link_path(@hash)
|
44
|
-
end
|
33
|
+
|
34
|
+
let :show_link_hash do
|
35
|
+
show_link.downloadKey
|
45
36
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
get 'generate_show', id:@file.pid
|
50
|
-
response.should be_success
|
51
|
-
assigns[:link].should == @routes.url_helpers.show_single_use_link_path(@hash)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
describe "unkown user" do
|
56
|
-
describe "GET 'generate_download'" do
|
57
|
-
it "and_return http failure" do
|
58
|
-
get 'generate_download', id:@file.pid
|
59
|
-
response.should_not be_success
|
60
|
-
end
|
37
|
+
|
38
|
+
let :download_link_hash do
|
39
|
+
download_link.downloadKey
|
61
40
|
end
|
62
|
-
|
63
|
-
describe "GET 'generate_show'" do
|
64
|
-
it "and_return http failure" do
|
65
|
-
get 'generate_show', id:@file.pid
|
66
|
-
response.should_not be_success
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
describe "retrieval links" do
|
71
|
-
before (:each) do
|
72
|
-
@dhash = SingleUseLink.create_download(@file.pid).downloadKey
|
73
|
-
@shash = SingleUseLink.create_show(@file.pid).downloadKey
|
74
|
-
end
|
41
|
+
|
75
42
|
before (:each) do
|
76
43
|
@user.delete
|
77
44
|
end
|
@@ -80,40 +47,42 @@ describe SingleUseLinkController do
|
|
80
47
|
controller.stub(:render)
|
81
48
|
expected_content = ActiveFedora::Base.find(@file.pid).content.content
|
82
49
|
controller.should_receive(:send_file_headers!).with({:filename => 'world.png', :disposition => 'inline', :type => 'image/png' })
|
83
|
-
get :download, id
|
50
|
+
get :download, id:download_link_hash
|
84
51
|
response.body.should == expected_content
|
85
52
|
response.should be_success
|
86
53
|
end
|
87
54
|
it "and_return 404 on second attempt" do
|
88
|
-
get :download, id
|
55
|
+
get :download, id:download_link_hash
|
89
56
|
response.should be_success
|
90
|
-
get :download, id
|
57
|
+
get :download, id:download_link_hash
|
91
58
|
response.should render_template('error/single_use_error')
|
92
59
|
end
|
93
60
|
it "and_return 404 on attempt to get download with show" do
|
94
|
-
get :download, id
|
61
|
+
get :download, id:download_link_hash
|
95
62
|
response.should be_success
|
96
|
-
get :
|
63
|
+
get :show, id:download_link_hash
|
97
64
|
response.should render_template('error/single_use_error')
|
98
65
|
end
|
99
66
|
end
|
100
67
|
|
101
68
|
describe "GET 'show'" do
|
102
69
|
it "and_return http success" do
|
103
|
-
|
70
|
+
|
71
|
+
get 'show', id:show_link_hash
|
104
72
|
response.should be_success
|
105
|
-
assigns[:
|
73
|
+
assigns[:asset].pid.should == @file.pid
|
106
74
|
end
|
107
75
|
it "and_return 404 on second attempt" do
|
108
|
-
get :show, id
|
76
|
+
get :show, id:show_link_hash
|
109
77
|
response.should be_success
|
110
|
-
get :show, id
|
78
|
+
get :show, id:show_link_hash
|
111
79
|
response.should render_template('error/single_use_error')
|
112
80
|
end
|
113
81
|
it "and_return 404 on attempt to get show path with download hash" do
|
114
|
-
get :show, id
|
82
|
+
get :show, id:download_link_hash
|
115
83
|
response.should render_template('error/single_use_error')
|
116
84
|
end
|
117
85
|
end
|
118
86
|
end
|
87
|
+
|
119
88
|
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Create and use single-use links" do
|
4
|
+
include Warden::Test::Helpers
|
5
|
+
Warden.test_mode!
|
6
|
+
include Sufia::Engine.routes.url_helpers
|
7
|
+
|
8
|
+
before do
|
9
|
+
user = User.find_by_email('jilluser@example.com') || FactoryGirl.create(:user)
|
10
|
+
|
11
|
+
login_as(user, :scope => :user)
|
12
|
+
|
13
|
+
|
14
|
+
@file = GenericFile.new
|
15
|
+
@file.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
16
|
+
@file.apply_depositor_metadata(user)
|
17
|
+
@file.save
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should generate a single-use link to show the record" do
|
21
|
+
visit generate_show_single_use_link_path(:id => @file)
|
22
|
+
|
23
|
+
expect(page).to have_css '.single-use-link a'
|
24
|
+
find('.single-use-link a').click
|
25
|
+
expect(page).to have_content 'world.png'
|
26
|
+
expect(page).to have_content "Download (can only be used once)"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should download the file contents" do
|
30
|
+
|
31
|
+
visit generate_download_single_use_link_path(:id => @file)
|
32
|
+
|
33
|
+
expect(page).to have_css '.download-link'
|
34
|
+
find('.download-link').click
|
35
|
+
expected_content = ActiveFedora::Base.find(@file.pid).content.content
|
36
|
+
expect(page.body).to eq expected_content
|
37
|
+
end
|
38
|
+
end
|
@@ -1,15 +1,19 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe SingleUseLink do
|
4
|
-
before
|
4
|
+
before(:all) do
|
5
5
|
@file = GenericFile.new
|
6
6
|
@file.apply_depositor_metadata('mjg36')
|
7
7
|
@file.save
|
8
8
|
end
|
9
|
+
|
9
10
|
after (:all) do
|
10
|
-
SingleUseLink.find(:all).each{ |l| l.delete}
|
11
11
|
@file.delete
|
12
12
|
end
|
13
|
+
|
14
|
+
let(:file) do
|
15
|
+
@file
|
16
|
+
end
|
13
17
|
|
14
18
|
describe "create" do
|
15
19
|
before do
|
@@ -20,35 +24,32 @@ describe SingleUseLink do
|
|
20
24
|
|
21
25
|
end
|
22
26
|
it "should create show link" do
|
23
|
-
su = SingleUseLink.
|
27
|
+
su = SingleUseLink.create itemId: file.pid, path: Sufia::Engine.routes.url_helpers.generic_file_path(file.pid)
|
24
28
|
su.downloadKey.should == @hash
|
25
|
-
su.itemId.should ==
|
26
|
-
su.path.should == Sufia::Engine.routes.url_helpers.generic_file_path(
|
29
|
+
su.itemId.should == file.pid
|
30
|
+
su.path.should == Sufia::Engine.routes.url_helpers.generic_file_path(file.pid)
|
27
31
|
su.delete
|
28
32
|
end
|
29
33
|
it "should create show download link" do
|
30
|
-
su = SingleUseLink.
|
34
|
+
su = SingleUseLink.create itemId: file.pid, path: Sufia::Engine.routes.url_helpers.download_path(file.pid)
|
31
35
|
su.downloadKey.should == @hash
|
32
|
-
su.itemId.should ==
|
33
|
-
su.path.should == Sufia::Engine.routes.url_helpers.download_path(
|
36
|
+
su.itemId.should == file.pid
|
37
|
+
su.path.should == Sufia::Engine.routes.url_helpers.download_path(file.pid)
|
34
38
|
su.delete
|
35
39
|
end
|
36
40
|
end
|
37
41
|
describe "find" do
|
38
42
|
describe "not expired" do
|
39
43
|
before do
|
40
|
-
@su = SingleUseLink.create(downloadKey:'sha2hashb', itemId
|
41
|
-
end
|
42
|
-
after do
|
43
|
-
@su.delete
|
44
|
+
@su = SingleUseLink.create(downloadKey:'sha2hashb', itemId:file.pid, path:Sufia::Engine.routes.url_helpers.download_path(file.noid), expires:DateTime.now.advance(:hours => 1))
|
44
45
|
end
|
45
46
|
it "should retrieve link" do
|
46
47
|
link = SingleUseLink.where(downloadKey:'sha2hashb').first
|
47
|
-
link.itemId.should ==
|
48
|
+
link.itemId.should == file.pid
|
48
49
|
end
|
49
50
|
it "should retrieve link with find_by" do
|
50
51
|
link = SingleUseLink.find_by_downloadKey('sha2hashb')
|
51
|
-
link.itemId.should ==
|
52
|
+
link.itemId.should == file.pid
|
52
53
|
end
|
53
54
|
it "should expire link" do
|
54
55
|
link = SingleUseLink.where(downloadKey:'sha2hashb').first
|
@@ -57,11 +58,11 @@ describe SingleUseLink do
|
|
57
58
|
end
|
58
59
|
describe "expired" do
|
59
60
|
before do
|
60
|
-
@su = SingleUseLink.create(downloadKey:'sha2hashb', itemId
|
61
|
-
|
62
|
-
|
63
|
-
@su.delete
|
61
|
+
@su = SingleUseLink.create!(downloadKey:'sha2hashb', itemId:file.pid, path:Sufia::Engine.routes.url_helpers.download_path(file.noid))
|
62
|
+
|
63
|
+
@su.update_attribute :expires, DateTime.now.advance(:hours => -1)
|
64
64
|
end
|
65
|
+
|
65
66
|
it "should expire link" do
|
66
67
|
link = SingleUseLink.where(downloadKey:'sha2hashb').first
|
67
68
|
link.expired?.should == true
|
@@ -3,18 +3,6 @@ require 'rails/generators'
|
|
3
3
|
class TestAppGenerator < Rails::Generators::Base
|
4
4
|
source_root File.expand_path("../../../../support", __FILE__)
|
5
5
|
|
6
|
-
def run_blacklight_generator
|
7
|
-
say_status("warning", "GENERATING BL", :yellow)
|
8
|
-
|
9
|
-
generate 'blacklight', '--devise'
|
10
|
-
end
|
11
|
-
|
12
|
-
def run_hydra_head_generator
|
13
|
-
say_status("warning", "GENERATING HH", :yellow)
|
14
|
-
|
15
|
-
generate 'hydra:head', '-f'
|
16
|
-
end
|
17
|
-
|
18
6
|
def run_sufia_generator
|
19
7
|
say_status("warning", "GENERATING SUFIA", :yellow)
|
20
8
|
|
@@ -2,5 +2,9 @@ class DomainTerm < ActiveRecord::Base
|
|
2
2
|
deprecated_attr_accessible :model, :term
|
3
3
|
|
4
4
|
# TODO we should add an index on this join table and remove the uniq query
|
5
|
-
|
5
|
+
if Rails::VERSION::MAJOR > 3
|
6
|
+
has_and_belongs_to_many :local_authorities, -> {uniq}
|
7
|
+
else
|
8
|
+
has_and_belongs_to_many :local_authorities, :uniq=> true
|
9
|
+
end
|
6
10
|
end
|
@@ -2,9 +2,15 @@ require 'rdf'
|
|
2
2
|
require 'rdf/rdfxml'
|
3
3
|
|
4
4
|
class LocalAuthority < ActiveRecord::Base
|
5
|
-
deprecated_attr_accessible
|
6
|
-
|
7
|
-
|
5
|
+
deprecated_attr_accessible :name
|
6
|
+
|
7
|
+
if Rails::VERSION::MAJOR >= 4
|
8
|
+
# TODO we should add an index on this join table and remove the uniq query
|
9
|
+
has_and_belongs_to_many :domain_terms, -> { uniq }
|
10
|
+
else
|
11
|
+
has_and_belongs_to_many :domain_terms, :uniq=> true
|
12
|
+
end
|
13
|
+
|
8
14
|
has_many :local_authority_entries
|
9
15
|
|
10
16
|
def self.harvest_rdf(name, sources, opts = {})
|
@@ -57,7 +63,7 @@ class LocalAuthority < ActiveRecord::Base
|
|
57
63
|
authority = self.find_by_name(name)
|
58
64
|
return if authority.blank?
|
59
65
|
model = model.to_s.sub(/RdfDatastream$/, '').underscore.pluralize
|
60
|
-
domain_term = DomainTerm.
|
66
|
+
domain_term = DomainTerm.find_or_create_by(model: model, term: term)
|
61
67
|
return if domain_term.local_authorities.include? authority
|
62
68
|
domain_term.local_authorities << authority
|
63
69
|
end
|
@@ -1,25 +1,44 @@
|
|
1
1
|
class SingleUseLink < ActiveRecord::Base
|
2
2
|
|
3
|
-
deprecated_attr_accessible
|
3
|
+
deprecated_attr_accessible :downloadKey, :path, :expires, :itemId
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
validate :expiration_date_cannot_be_in_the_past
|
6
|
+
validate :cannot_be_destroyed
|
7
|
+
|
8
|
+
after_initialize :set_defaults
|
9
9
|
|
10
|
-
def
|
11
|
-
|
10
|
+
def create_for_path path
|
11
|
+
self.class.create :itemId => itemId, :path => path
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
def expired?
|
15
|
-
|
16
|
-
return (now > expires)
|
15
|
+
DateTime.now > expires
|
17
16
|
end
|
18
|
-
|
17
|
+
|
18
|
+
|
19
|
+
def to_param
|
20
|
+
downloadKey
|
21
|
+
end
|
22
|
+
|
19
23
|
protected
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
+
|
25
|
+
def expiration_date_cannot_be_in_the_past
|
26
|
+
if expired?
|
27
|
+
errors.add(:expires, "can't be in the past")
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def cannot_be_destroyed
|
32
|
+
if destroyed?
|
33
|
+
errors[:base] << "Single Use Link has already been used"
|
34
|
+
end
|
24
35
|
end
|
25
|
-
|
36
|
+
|
37
|
+
def set_defaults
|
38
|
+
if new_record?
|
39
|
+
self.expires ||= DateTime.now.advance(hours:24)
|
40
|
+
self.downloadKey ||= (Digest::SHA2.new << rand(1000000000).to_s).to_s
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -37,7 +37,7 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.add_dependency 'resque-pool', '0.3.0'
|
38
38
|
spec.add_dependency 'noid', '~> 0.6.6'
|
39
39
|
spec.add_dependency 'mailboxer', '~> 0.11.0'
|
40
|
-
spec.add_dependency 'acts_as_follower', '0.1.1'
|
40
|
+
spec.add_dependency 'acts_as_follower', '>= 0.1.1', '< 0.3'
|
41
41
|
spec.add_dependency 'paperclip', '~> 3.4.0'
|
42
42
|
spec.add_dependency 'zipruby', '0.3.6'
|
43
43
|
spec.add_dependency 'hydra-derivatives', '~> 0.0.5'
|
data/sufia.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.license = 'APACHE2'
|
19
19
|
|
20
20
|
gem.add_dependency 'sufia-models', version
|
21
|
-
gem.add_dependency 'blacklight', '~> 4.0'
|
21
|
+
gem.add_dependency 'blacklight', '~> 4.0', '< 4.4' # blacklight 4.4.1/0 doesn't work with kaminari > 0.14.1
|
22
22
|
gem.add_dependency 'blacklight_advanced_search', '~> 2.1.0'
|
23
23
|
|
24
24
|
gem.add_dependency 'hydra-batch-edit', '~> 1.0'
|
data/tasks/release.rake
CHANGED
@@ -32,7 +32,6 @@ tag = "v#{version}"
|
|
32
32
|
File.open(file, 'w') { |f| f.write ruby }
|
33
33
|
end
|
34
34
|
end
|
35
|
-
task :pkg
|
36
35
|
task gem => %w(update_version_rb pkg) do
|
37
36
|
cmd = ""
|
38
37
|
cmd << "cd #{framework} && " unless framework == "sufia"
|
@@ -48,7 +47,7 @@ tag = "v#{version}"
|
|
48
47
|
task :prep_release => [:ensure_clean_state, :build]
|
49
48
|
|
50
49
|
task :push => :build do
|
51
|
-
|
50
|
+
sh "gem push #{gem}"
|
52
51
|
end
|
53
52
|
end
|
54
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sufia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-09-
|
11
|
+
date: 2013-09-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sufia-models
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - '='
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.
|
19
|
+
version: 3.3.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - '='
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.
|
26
|
+
version: 3.3.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: blacklight
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -31,6 +31,9 @@ dependencies:
|
|
31
31
|
- - ~>
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '4.0'
|
34
|
+
- - <
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: '4.4'
|
34
37
|
type: :runtime
|
35
38
|
prerelease: false
|
36
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -38,6 +41,9 @@ dependencies:
|
|
38
41
|
- - ~>
|
39
42
|
- !ruby/object:Gem::Version
|
40
43
|
version: '4.0'
|
44
|
+
- - <
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '4.4'
|
41
47
|
- !ruby/object:Gem::Dependency
|
42
48
|
name: blacklight_advanced_search
|
43
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -268,7 +274,8 @@ files:
|
|
268
274
|
- app/controllers/errors_controller.rb
|
269
275
|
- app/controllers/generic_files_controller.rb
|
270
276
|
- app/controllers/mailbox_controller.rb
|
271
|
-
- app/controllers/
|
277
|
+
- app/controllers/single_use_links_controller.rb
|
278
|
+
- app/controllers/single_use_links_viewer_controller.rb
|
272
279
|
- app/controllers/static_controller.rb
|
273
280
|
- app/controllers/users_controller.rb
|
274
281
|
- app/helpers/batch_edits_helper.rb
|
@@ -445,9 +452,9 @@ files:
|
|
445
452
|
- app/views/layouts/sufia-one-column.html.erb
|
446
453
|
- app/views/layouts/sufia-two-column.html.erb
|
447
454
|
- app/views/mailbox/index.html.erb
|
448
|
-
- app/views/
|
449
|
-
- app/views/
|
450
|
-
- app/views/
|
455
|
+
- app/views/single_use_links/new_download.html.erb
|
456
|
+
- app/views/single_use_links/new_show.html.erb
|
457
|
+
- app/views/single_use_links_viewer/show.html.erb
|
451
458
|
- app/views/static/about.html.erb
|
452
459
|
- app/views/static/agreement.html.erb
|
453
460
|
- app/views/static/help.html.erb
|
@@ -516,7 +523,8 @@ files:
|
|
516
523
|
- spec/controllers/downloads_controller_spec.rb
|
517
524
|
- spec/controllers/generic_files_controller_spec.rb
|
518
525
|
- spec/controllers/mailbox_controller_spec.rb
|
519
|
-
- spec/controllers/
|
526
|
+
- spec/controllers/single_use_links_controller_spec.rb
|
527
|
+
- spec/controllers/single_use_links_viewer_controller_spec.rb
|
520
528
|
- spec/controllers/users_controller_spec.rb
|
521
529
|
- spec/factories/checksum_audit_logs.rb
|
522
530
|
- spec/factories/single_use_links.rb
|
@@ -526,6 +534,7 @@ files:
|
|
526
534
|
- spec/features/contact_form.rb
|
527
535
|
- spec/features/display_dashboard.rb
|
528
536
|
- spec/features/ingest_upload_files.rb
|
537
|
+
- spec/features/single_use_links_spec.rb
|
529
538
|
- spec/features/users_spec.rb
|
530
539
|
- spec/fixtures/4-20.png
|
531
540
|
- spec/fixtures/Example.ogg
|
@@ -754,7 +763,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
754
763
|
version: '0'
|
755
764
|
requirements: []
|
756
765
|
rubyforge_project:
|
757
|
-
rubygems_version: 2.0.
|
766
|
+
rubygems_version: 2.0.5
|
758
767
|
signing_key:
|
759
768
|
specification_version: 4
|
760
769
|
summary: Sufia was extracted from ScholarSphere developed by Penn State University
|
@@ -770,7 +779,8 @@ test_files:
|
|
770
779
|
- spec/controllers/downloads_controller_spec.rb
|
771
780
|
- spec/controllers/generic_files_controller_spec.rb
|
772
781
|
- spec/controllers/mailbox_controller_spec.rb
|
773
|
-
- spec/controllers/
|
782
|
+
- spec/controllers/single_use_links_controller_spec.rb
|
783
|
+
- spec/controllers/single_use_links_viewer_controller_spec.rb
|
774
784
|
- spec/controllers/users_controller_spec.rb
|
775
785
|
- spec/factories/checksum_audit_logs.rb
|
776
786
|
- spec/factories/single_use_links.rb
|
@@ -780,6 +790,7 @@ test_files:
|
|
780
790
|
- spec/features/contact_form.rb
|
781
791
|
- spec/features/display_dashboard.rb
|
782
792
|
- spec/features/ingest_upload_files.rb
|
793
|
+
- spec/features/single_use_links_spec.rb
|
783
794
|
- spec/features/users_spec.rb
|
784
795
|
- spec/fixtures/4-20.png
|
785
796
|
- spec/fixtures/Example.ogg
|
@@ -866,3 +877,4 @@ test_files:
|
|
866
877
|
- spec/support/lib/generators/test_app_generator.rb
|
867
878
|
- spec/support/uploaded_file_monkeypatch.rb
|
868
879
|
- spec/views/batch_edits/check_all_spec.rb
|
880
|
+
has_rdoc:
|
@@ -1,95 +0,0 @@
|
|
1
|
-
require 'sufia/single_use_error'
|
2
|
-
|
3
|
-
class SingleUseLinkController < DownloadsController
|
4
|
-
before_filter :authenticate_user!, :except => [:download, :show]
|
5
|
-
before_filter :find_file, :only => [:generate_download, :generate_show]
|
6
|
-
before_filter :authorize_user!, :only => [:generate_download, :generate_show]
|
7
|
-
skip_filter :normalize_identifier, :load_asset, :load_datastream
|
8
|
-
prepend_before_filter :normalize_identifier, :except => [:download, :show]
|
9
|
-
rescue_from Sufia::SingleUseError, :with => :render_single_use_error
|
10
|
-
|
11
|
-
def generate_download
|
12
|
-
@su = SingleUseLink.create_download(params[:id])
|
13
|
-
@link = sufia.download_single_use_link_path(@su.downloadKey)
|
14
|
-
respond_to do |format|
|
15
|
-
format.html
|
16
|
-
format.js {render :js => @link}
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def generate_show
|
21
|
-
@su = SingleUseLink.create_show(params[:id])
|
22
|
-
@link = sufia.show_single_use_link_path(@su.downloadKey)
|
23
|
-
respond_to do |format|
|
24
|
-
format.html
|
25
|
-
format.js {render :js => @link}
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
def download
|
30
|
-
#look up the item
|
31
|
-
link = lookup_hash
|
32
|
-
|
33
|
-
#grab the item id
|
34
|
-
id = link.itemId
|
35
|
-
|
36
|
-
#check to make sure the path matches
|
37
|
-
not_found if link.path != sufia.download_path(id)
|
38
|
-
|
39
|
-
# send the data content
|
40
|
-
@asset = GenericFile.load_instance_from_solr(id)
|
41
|
-
load_datastream
|
42
|
-
send_content(asset)
|
43
|
-
end
|
44
|
-
|
45
|
-
def show
|
46
|
-
link = lookup_hash
|
47
|
-
|
48
|
-
#grab the item id
|
49
|
-
id = link.itemId
|
50
|
-
|
51
|
-
#check to make sure the path matches
|
52
|
-
not_found if link.path != sufia.generic_file_path(id)
|
53
|
-
|
54
|
-
#show the file
|
55
|
-
@generic_file = GenericFile.load_instance_from_solr(id)
|
56
|
-
@terms = @generic_file.terms_for_display
|
57
|
-
|
58
|
-
# create a dowload link that is single use for the user since we do not just want to show metadata we want to access it too
|
59
|
-
@su = SingleUseLink.create_download(id)
|
60
|
-
@download_link = sufia.download_single_use_link_path(@su.downloadKey)
|
61
|
-
end
|
62
|
-
|
63
|
-
protected
|
64
|
-
|
65
|
-
def authorize_user!
|
66
|
-
authorize! :read, @generic_file
|
67
|
-
end
|
68
|
-
|
69
|
-
def find_file
|
70
|
-
@generic_file = GenericFile.load_instance_from_solr(params[:id])
|
71
|
-
end
|
72
|
-
|
73
|
-
def lookup_hash
|
74
|
-
id = params[:id]
|
75
|
-
# invalid hash send not found
|
76
|
-
link = SingleUseLink.where(downloadKey:id).first || not_found
|
77
|
-
|
78
|
-
# expired hash send not found
|
79
|
-
now = DateTime.now
|
80
|
-
not_found if link.expires <= now
|
81
|
-
|
82
|
-
# delete the link since it has been used
|
83
|
-
link.destroy
|
84
|
-
|
85
|
-
return link
|
86
|
-
end
|
87
|
-
|
88
|
-
def not_found
|
89
|
-
raise Sufia::SingleUseError.new('Single-Use Link Not Found')
|
90
|
-
end
|
91
|
-
|
92
|
-
def expired
|
93
|
-
raise Sufia::SingleUseError.new('Single-Use Link Expired')
|
94
|
-
end
|
95
|
-
end
|
@@ -1,3 +0,0 @@
|
|
1
|
-
<h1>Single Use Link</h1>
|
2
|
-
<p>Anyone can use the following link once to download the file</p>
|
3
|
-
<%= link_to @generic_file, @link %> <%= link_to raw('<i class="icon-link icon-large"></i>'), '#', :class => 'copypaste itemicon itemcode', :title => 'Copy File URL', :id => "copy_link_#{@generic_file.pid}" %>
|