ddr-models 1.2.1 → 1.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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +75 -1
  3. data/app/models/attachment.rb +6 -1
  4. data/app/models/collection.rb +19 -1
  5. data/app/models/component.rb +6 -1
  6. data/app/models/item.rb +6 -1
  7. data/app/models/solr_document.rb +3 -0
  8. data/app/models/target.rb +8 -1
  9. data/config/initializers/devise.rb~ +245 -0
  10. data/db/migrate/20141104181418_create_users.rb~ +6 -0
  11. data/lib/ddr/auth.rb +6 -1
  12. data/lib/ddr/auth.rb~ +47 -0
  13. data/lib/ddr/auth/ability.rb +5 -0
  14. data/lib/ddr/auth/ability.rb~ +204 -0
  15. data/lib/ddr/auth/group_service.rb~ +53 -0
  16. data/lib/ddr/auth/grouper_service.rb~ +77 -0
  17. data/lib/ddr/auth/remote_group_service.rb~ +35 -0
  18. data/lib/ddr/auth/superuser.rb~ +9 -0
  19. data/lib/ddr/auth/user.rb~ +65 -0
  20. data/lib/ddr/index_fields.rb +2 -2
  21. data/lib/ddr/models.rb +21 -4
  22. data/lib/ddr/models/engine.rb +26 -13
  23. data/lib/ddr/models/version.rb +1 -1
  24. data/lib/ddr/services/id_service.rb +4 -2
  25. data/spec/dummy/db/development.sqlite3 +0 -0
  26. data/spec/dummy/log/development.log +2727 -1701
  27. data/spec/dummy/log/test.log +56845 -35270
  28. data/spec/factories/attachment_factories.rb +0 -4
  29. data/spec/factories/collection_factories.rb +0 -8
  30. data/spec/factories/component_factories.rb +1 -6
  31. data/spec/factories/item_factories.rb +0 -8
  32. data/spec/factories/user_factories.rb~ +7 -0
  33. data/spec/features/grouper_integration_spec.rb~ +21 -0
  34. data/spec/models/ability_spec.rb +11 -24
  35. data/spec/models/ability_spec.rb~ +245 -0
  36. data/spec/models/superuser_spec.rb~ +13 -0
  37. data/spec/models/user_spec.rb~ +56 -0
  38. data/spec/services/group_service_spec.rb~ +71 -0
  39. data/spec/spec_helper.rb +16 -25
  40. metadata +23 -18
  41. data/config/initializers/ddr.rb +0 -8
  42. data/lib/ddr/configurable.rb +0 -34
@@ -6,10 +6,6 @@ FactoryGirl.define do
6
6
  after(:build) do |a|
7
7
  a.upload File.new(File.join(Ddr::Models::Engine.root.to_s, 'spec', 'fixtures', 'sample.docx'))
8
8
  end
9
-
10
- trait :attached do
11
- association :attached_to, :factory => :test_model_omnibus
12
- end
13
9
  end
14
10
 
15
11
  end
@@ -3,14 +3,6 @@ FactoryGirl.define do
3
3
  factory :collection do
4
4
  title [ "Test Collection" ]
5
5
  sequence(:identifier) { |n| [ "coll%05d" % n ] }
6
-
7
- trait :has_item do
8
- children { [ FactoryGirl.create(:item) ] }
9
- end
10
-
11
- trait :has_target do
12
- targets { [ FactoryGirl.create(:target) ] }
13
- end
14
6
  end
15
7
 
16
8
  end
@@ -5,11 +5,6 @@ FactoryGirl.define do
5
5
  sequence(:identifier) { |n| [ "cmp%05d" % n ] }
6
6
  after(:build) do |c|
7
7
  c.upload File.new(File.join(Ddr::Models::Engine.root.to_s, "spec", "fixtures", "library-devil.tiff"))
8
- end
9
-
10
- trait :has_parent do
11
- item
12
- end
13
-
8
+ end
14
9
  end
15
10
  end
@@ -3,14 +3,6 @@ FactoryGirl.define do
3
3
  factory :item do
4
4
  title [ "Test Item" ]
5
5
  sequence(:identifier) { |n| [ "item%05d" % n ] }
6
-
7
- trait :member_of_collection do
8
- collection
9
- end
10
-
11
- trait :has_part do
12
- children { [ FactoryGirl.create(:component) ] }
13
- end
14
6
  end
15
7
 
16
8
  end
@@ -0,0 +1,7 @@
1
+ FactoryGirl.define do
2
+ factory :user, class: Ddr::Auth::User do
3
+ sequence(:username) { |n| "person#{n}" }
4
+ email { |u| "#{u.username}@example.com" }
5
+ password "secret"
6
+ end
7
+ end
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+ require 'dul_hydra'
3
+
4
+ describe "Grouper integration", :type => :feature do
5
+ let(:user) { FactoryGirl.create(:user) }
6
+ let(:object) { FactoryGirl.create(:collection) }
7
+ before do
8
+ object.title = [ "Grouper Works!" ]
9
+ object.read_groups = ["duke:library:repository:ddr:foo:bar"]
10
+ object.save!
11
+ Warden.on_next_request do |proxy|
12
+ proxy.env[DulHydra.remote_groups_env_key] = "urn:mace:duke.edu:groups:library:repository:ddr:foo:bar"
13
+ proxy.set_user user
14
+ end
15
+ end
16
+ it "should honor Grouper group access control" do
17
+ visit url_for(object)
18
+ expect(page).to have_content("Grouper Works!")
19
+ end
20
+
21
+ end
@@ -8,6 +8,17 @@ module Ddr
8
8
  subject { described_class.new(user) }
9
9
  let(:user) { FactoryGirl.create(:user) }
10
10
 
11
+ describe "collection permissions" do
12
+ before { allow(Ddr::Auth).to receive(:collection_creators_group) { "Collection Creators" } }
13
+ context "user is a collection creator" do
14
+ before { allow(user).to receive(:groups) { ["Collection Creators"] } }
15
+ it { is_expected.to be_able_to(:create, Collection) }
16
+ end
17
+ context "user is not a collection creator" do
18
+ it { is_expected.not_to be_able_to(:create, Collection) }
19
+ end
20
+ end
21
+
11
22
  describe "#upload_permissions", uploads: true do
12
23
  let(:resource) { FactoryGirl.build(:component) }
13
24
  context "user has edit permission" do
@@ -181,30 +192,6 @@ module Ddr
181
192
  end
182
193
  end
183
194
 
184
- # describe "#export_sets_permissions", export_sets: true do
185
- # let(:resource) { ExportSet.new(user: user) }
186
- # context "associated user" do
187
- # it { is_expected.to be_able_to(:manage, resource) }
188
- # end
189
- # context "other user" do
190
- # subject { described_class.new(other_user) }
191
- # let(:other_user) { FactoryGirl.create(:user) }
192
- # it { is_expected.not_to be_able_to(:read, resource) }
193
- # end
194
- # end
195
-
196
- # describe "#ingest_folders_permissions", ingest_folders: true do
197
- # let(:resource) { IngestFolder }
198
- # context "user has no permitted ingest folders" do
199
- # before { allow(resource).to receive(:permitted_folders).with(user).and_return([]) }
200
- # it { is_expected.not_to be_able_to(:create, resource) }
201
- # end
202
- # context "user has at least one permitted ingest folder" do
203
- # before { allow(resource).to receive(:permitted_folders).with(user).and_return(['dir']) }
204
- # it { is_expected.to be_able_to(:create, resource) }
205
- # end
206
- # end
207
-
208
195
  describe "#attachment_permissions", attachments: true do
209
196
  context "object can have attachments" do
210
197
  let(:resource) { FactoryGirl.build(:test_model_omnibus) }
@@ -0,0 +1,245 @@
1
+ require 'spec_helper'
2
+ require 'dul_hydra'
3
+ require 'cancan/matchers'
4
+
5
+ describe Ability, type: :model, abilities: true do
6
+
7
+ subject { described_class.new(user) }
8
+ let(:user) { FactoryGirl.create(:user) }
9
+
10
+ describe "#upload_permissions", uploads: true do
11
+ let(:resource) { FactoryGirl.build(:component) }
12
+ context "user has edit permission" do
13
+ before { subject.can(:edit, resource) }
14
+ it { is_expected.to be_able_to(:upload, resource) }
15
+ end
16
+ context "user does not have edit permission" do
17
+ before { subject.cannot(:edit, resource) }
18
+ it { is_expected.not_to be_able_to(:upload, resource) }
19
+ end
20
+ end
21
+
22
+ describe "#download_permissions", downloads: true do
23
+ context "on an object" do
24
+ context "which is a Component", components: true do
25
+ let!(:resource) { FactoryGirl.create(:component) }
26
+ context "and user does NOT have the downloader role" do
27
+ context "and user has edit permission" do
28
+ before do
29
+ resource.edit_users = [user.user_key]
30
+ resource.save
31
+ end
32
+ it { is_expected.to be_able_to(:download, resource) }
33
+ end
34
+ context "and user has read permission" do
35
+ before do
36
+ resource.read_users = [user.user_key]
37
+ resource.save
38
+ end
39
+ it { is_expected.not_to be_able_to(:download, resource) }
40
+ end
41
+ context "and user lacks read permission" do
42
+ it { is_expected.not_to be_able_to(:download, resource) }
43
+ end
44
+ end
45
+
46
+ context "and user has the downloader role", roles: true do
47
+ before do
48
+ resource.roleAssignments.downloader << user.principal_name
49
+ resource.save
50
+ end
51
+ context "and user has edit permission" do
52
+ before do
53
+ resource.edit_users = [user.user_key]
54
+ resource.save
55
+ end
56
+ it { is_expected.to be_able_to(:download, resource) }
57
+ end
58
+ context "and user has read permission" do
59
+ before do
60
+ resource.read_users = [user.user_key]
61
+ resource.save
62
+ end
63
+ it { is_expected.to be_able_to(:download, resource) }
64
+ end
65
+ context "and user lacks read permission" do
66
+ it { is_expected.not_to be_able_to(:download, resource) }
67
+ end
68
+ end
69
+ end
70
+
71
+ context "which is not a Component" do
72
+ let(:resource) { FactoryGirl.create(:test_content) }
73
+ context "and user has read permission" do
74
+ before do
75
+ resource.read_users = [user.user_key]
76
+ resource.save
77
+ end
78
+ it { is_expected.to be_able_to(:download, resource) }
79
+ end
80
+ context "and user lacks read permission" do
81
+ it { is_expected.not_to be_able_to(:download, resource) }
82
+ end
83
+ end
84
+ end
85
+
86
+ context "on a datastream", datastreams: true do
87
+
88
+ context "named 'content'", content: true do
89
+ let(:resource) { obj.content }
90
+ context "and object is a Component", components: true do
91
+ let(:obj) { FactoryGirl.create(:component) }
92
+ context "and user does not have the downloader role" do
93
+ context "and user has read permission on the object" do
94
+ before do
95
+ obj.read_users = [user.user_key]
96
+ obj.save
97
+ end
98
+ it { is_expected.not_to be_able_to(:download, resource) }
99
+ end
100
+ context "and user lacks read permission on the object" do
101
+ it { is_expected.not_to be_able_to(:download, resource) }
102
+ end
103
+ end
104
+
105
+ context "and user has the downloader role", roles: true do
106
+ before do
107
+ obj.roleAssignments.downloader << user.principal_name
108
+ obj.save
109
+ end
110
+ context "and user has read permission on the object" do
111
+ before do
112
+ obj.read_users = [user.user_key]
113
+ obj.save
114
+ end
115
+ it { is_expected.to be_able_to(:download, resource) }
116
+ end
117
+ context "and user lacks read permission on the object" do
118
+ it { is_expected.not_to be_able_to(:download, resource) }
119
+ end
120
+ end
121
+ end
122
+
123
+ context "and object is not a Component" do
124
+ let(:obj) { FactoryGirl.create(:test_content) }
125
+ context "and user has read permission on the object" do
126
+ before do
127
+ obj.read_users = [user.user_key]
128
+ obj.save
129
+ end
130
+ it { is_expected.to be_able_to(:download, resource) }
131
+ end
132
+ context "and user lacks read permission on the object" do
133
+ it { is_expected.not_to be_able_to(:download, resource) }
134
+ end
135
+ end
136
+
137
+ end
138
+
139
+ context "not named 'content'" do
140
+ let(:obj) { FactoryGirl.create(:test_model) }
141
+ let(:resource) { obj.descMetadata }
142
+ context "and user has read permission on the object" do
143
+ before do
144
+ obj.read_users = [user.user_key]
145
+ obj.save
146
+ end
147
+ it { is_expected.to be_able_to(:download, resource) }
148
+ end
149
+ context "and user lacks read permission on the object" do
150
+ it { is_expected.not_to be_able_to(:download, resource) }
151
+ end
152
+ end
153
+
154
+ end
155
+
156
+ end # download_permissions
157
+
158
+ describe "#discover_permissions" do
159
+ # TODO
160
+ end
161
+
162
+ describe "#events_permissions", events: true do
163
+ let(:object) { FactoryGirl.create(:test_model) }
164
+ let(:resource) { Ddr::Events::Event.new(pid: object.pid) }
165
+ context "event is associated with a user" do
166
+ before { resource.user = user }
167
+ it { is_expected.to be_able_to(:read, resource) }
168
+ end
169
+ context "event is not associated with a user" do
170
+ context "and can read object" do
171
+ before do
172
+ object.read_users = [user.user_key]
173
+ object.save!
174
+ end
175
+ it { is_expected.to be_able_to(:read, resource) }
176
+ end
177
+ context "and cannot read object" do
178
+ it { is_expected.not_to be_able_to(:read, resource) }
179
+ end
180
+ end
181
+ end
182
+
183
+ describe "#export_sets_permissions", export_sets: true do
184
+ let(:resource) { ExportSet.new(user: user) }
185
+ context "associated user" do
186
+ it { is_expected.to be_able_to(:manage, resource) }
187
+ end
188
+ context "other user" do
189
+ subject { described_class.new(other_user) }
190
+ let(:other_user) { FactoryGirl.create(:user) }
191
+ it { is_expected.not_to be_able_to(:read, resource) }
192
+ end
193
+ end
194
+
195
+ describe "#ingest_folders_permissions", ingest_folders: true do
196
+ let(:resource) { IngestFolder }
197
+ context "user has no permitted ingest folders" do
198
+ before { allow(resource).to receive(:permitted_folders).with(user).and_return([]) }
199
+ it { is_expected.not_to be_able_to(:create, resource) }
200
+ end
201
+ context "user has at least one permitted ingest folder" do
202
+ before { allow(resource).to receive(:permitted_folders).with(user).and_return(['dir']) }
203
+ it { is_expected.to be_able_to(:create, resource) }
204
+ end
205
+ end
206
+
207
+ describe "#attachment_permissions", attachments: true do
208
+ context "object can have attachments" do
209
+ let(:resource) { FactoryGirl.build(:test_model_omnibus) }
210
+ context "and user lacks edit rights" do
211
+ before { subject.cannot(:edit, resource) }
212
+ it { is_expected.not_to be_able_to(:add_attachment, resource) }
213
+ end
214
+ context "and user has edit rights" do
215
+ before { subject.can(:edit, resource) }
216
+ it { is_expected.to be_able_to(:add_attachment, resource) }
217
+ end
218
+ end
219
+ context "object cannot have attachments" do
220
+ let(:resource) { FactoryGirl.build(:test_model) }
221
+ before { subject.can(:edit, resource) }
222
+ it { is_expected.not_to be_able_to(:add_attachment, resource) }
223
+ end
224
+ end
225
+
226
+ describe "#children_permissions", children: true do
227
+ context "user has edit rights on object" do
228
+ before { subject.can(:edit, resource) }
229
+ context "and object can have children" do
230
+ let(:resource) { FactoryGirl.build(:collection) }
231
+ it { is_expected.to be_able_to(:add_children, resource) }
232
+ end
233
+ context "but object cannot have children" do
234
+ let(:resource) { FactoryGirl.build(:component) }
235
+ it { is_expected.not_to be_able_to(:add_children, resource) }
236
+ end
237
+ end
238
+ context "user lacks edit rights on attached_to object" do
239
+ let(:resource) { FactoryGirl.build(:collection) }
240
+ before { subject.cannot(:edit, resource) }
241
+ it { is_expected.not_to be_able_to(:add_children, resource) }
242
+ end
243
+ end
244
+
245
+ end
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+ require 'cancan/matchers'
3
+
4
+ module Ddr
5
+ module Auth
6
+ describe Superuser, type: :model, abilities: true do
7
+ subject { described_class.new }
8
+ it "should be able to manage all" do
9
+ expect(subject).to be_able_to(:manage, :all)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ describe User, :type => :model do
4
+
5
+ subject { FactoryGirl.build(:user) }
6
+
7
+ describe "#member_of?" do
8
+ it "should return true if the user is a member of the group" do
9
+ allow(subject).to receive(:groups).and_return(["foo", "bar"])
10
+ expect(subject).to be_member_of("foo")
11
+ end
12
+ it "should return false if the user is not a member of the group" do
13
+ allow(subject).to receive(:groups).and_return(["foo", "bar"])
14
+ expect(subject).not_to be_member_of("baz")
15
+ end
16
+ end
17
+
18
+ describe "#authorized_to_act_as_superuser?" do
19
+ it "should return false if the superuser group is not defined (nil)" do
20
+ DulHydra.superuser_group = nil
21
+ expect(subject).not_to be_authorized_to_act_as_superuser
22
+ end
23
+ it "should return false if the user is not a member of the superuser group" do
24
+ DulHydra.superuser_group = "superusers"
25
+ allow(subject).to receive(:groups).and_return(["normal"])
26
+ expect(subject).not_to be_authorized_to_act_as_superuser
27
+ end
28
+ it "should return true if the user is a member of the superuser group" do
29
+ DulHydra.superuser_group = "superusers"
30
+ allow(subject).to receive(:groups).and_return(["superusers"])
31
+ expect(subject).to be_authorized_to_act_as_superuser
32
+ end
33
+ end
34
+
35
+ describe "#principal_name" do
36
+ it "should return the principal name for the user" do
37
+ expect(subject.principal_name).to eq subject.user_key
38
+ end
39
+ end
40
+
41
+ describe "#principals" do
42
+ it "should be a list of the user's groups + the user's principal_name" do
43
+ allow(subject).to receive(:groups) { ["foo", "bar"] }
44
+ expect(subject.principals).to match_array ["foo", "bar", subject.principal_name]
45
+ end
46
+ end
47
+
48
+ describe "#has_role?" do
49
+ let(:obj) { double }
50
+ it "should send :principal_has_role? to the object with the user's principals" do
51
+ expect(obj).to receive(:principal_has_role?).with(subject.principals, :administrator)
52
+ subject.has_role?(obj, :administrator)
53
+ end
54
+ end
55
+
56
+ end