hydra-access-controls 0.0.1

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.
@@ -0,0 +1,33 @@
1
+ # this code will be moved/renamed to Hydra::AccessControl::RoleMapperBehavior (with the appropriate namespace changes) in Hydra 5.0
2
+ require 'yaml'
3
+ module Hydra::RoleMapperBehavior
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ def role_names
8
+ map.keys
9
+ end
10
+ def roles(username)
11
+ byname[username]||[]
12
+ end
13
+
14
+ def whois(r)
15
+ map[r]||[]
16
+ end
17
+
18
+ def map
19
+ @map ||= YAML.load(File.open(File.join(Rails.root, "config/role_map_#{Rails.env}.yml")))
20
+ end
21
+
22
+
23
+ def byname
24
+ return @byname if @byname
25
+ m = Hash.new{|h,k| h[k]=[]}
26
+ @byname = map.inject(m) do|memo, (role,usernames)|
27
+ ((usernames if usernames.respond_to?(:each)) || [usernames]).each { |x| memo[x]<<role}
28
+ memo
29
+ end
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,6 @@
1
+ # RoleMapper This is used by AccessControlsEnforcement to get users' Roles (used in access permissions)
2
+ # If you are using something like Shibboleth or LDAP to get users' Roles, you should override this Class.
3
+ # Your override should include a Module that implements the same behaviors as Hydra::RoleMapperBehavior
4
+ class RoleMapper
5
+ include Hydra::RoleMapperBehavior
6
+ end
@@ -0,0 +1,20 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+
5
+
6
+ # if ENV['COVERAGE'] and RUBY_VERSION =~ /^1.9/
7
+ # require 'simplecov'
8
+ # require 'simplecov-rcov'
9
+ #
10
+ # SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter
11
+ # SimpleCov.start
12
+ # end
13
+ #
14
+ require 'rspec/autorun'
15
+ require 'hydra-access-controls'
16
+ require 'support/mods_asset'
17
+ RSpec.configure do |config|
18
+
19
+ end
20
+
@@ -0,0 +1,14 @@
1
+ archivist:
2
+ - archivist1@example.com
3
+ - archivist2@example.com
4
+ - leland_himself@example.com
5
+ admin_policy_object_editor:
6
+ - archivist1@example.com
7
+ donor:
8
+ - donor1@example.com
9
+ - leland_himself@example.com
10
+ researcher:
11
+ - researcher1@example.com
12
+ patron:
13
+ - patron1@example.com
14
+ - leland_himself@example.com
@@ -0,0 +1,6 @@
1
+ require 'active-fedora'
2
+ class ModsAsset < ActiveFedora::Base
3
+ include Hydra::ModelMixins::RightsMetadata
4
+ has_metadata :name => "rightsMetadata", :type => Hydra::Datastream::RightsMetadata
5
+
6
+ end
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ability do
4
+ before do
5
+ class Rails; end
6
+ class User; end
7
+ class Devise; end
8
+ class SolrDocument
9
+ def initialize(one, two)
10
+ @one = one
11
+ end
12
+ def fetch(field, default)
13
+ @one[field]
14
+ end
15
+ end
16
+ class Hydra::SuperuserAttributes; end
17
+ module Blacklight
18
+ module Exceptions
19
+ class InvalidSolrID < StandardError
20
+ def initialize(opt)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ Devise.stub(:authentication_keys).and_return(['email'])
26
+ # User.any_instance.stub(:email).and_return('archivist1@example.com')
27
+ # User.any_instance.stub(:new_record?).and_return(false)
28
+ # User.any_instance.stub(:is_being_superuser?).and_return(false)
29
+ Hydra::SuperuserAttributes.stub(:silenced)
30
+ Hydra::SuperuserAttributes.stub(:silenced=)
31
+ @solr_resp = stub("solr response")
32
+ Blacklight.stub(:solr).and_return(stub("solr", :find=>@solr_resp))
33
+
34
+ Rails.stub(:root).and_return('spec/support')
35
+ Rails.stub(:env).and_return('test')
36
+
37
+ Hydra.stub(:config).and_return({:permissions=>{
38
+ :catchall => "access_t",
39
+ :discover => {:group =>"discover_access_group_t", :individual=>"discover_access_person_t"},
40
+ :read => {:group =>"read_access_group_t", :individual=>"read_access_person_t"},
41
+ :edit => {:group =>"edit_access_group_t", :individual=>"edit_access_person_t"},
42
+ :owner => "depositor_t",
43
+ :embargo_release_date => "embargo_release_date_dt"
44
+ }})
45
+ end
46
+
47
+ context "for a not-signed in user" do
48
+ before do
49
+ User.any_instance.stub(:email).and_return(nil)
50
+ User.any_instance.stub(:new_record?).and_return(true)
51
+ User.any_instance.stub(:is_being_superuser?).and_return(false)
52
+ end
53
+ subject { Ability.new(nil) }
54
+ it "should call custom_permissions" do
55
+ Ability.any_instance.should_receive(:custom_permissions)
56
+ subject.can?(:delete, 7)
57
+ end
58
+ it "should be able to read objects that are public" do
59
+ @solr_resp.stub(:docs).and_return([{'read_access_group_t' =>['public']}])
60
+ public_object = ModsAsset.new
61
+ subject.can?(:read, public_object).should be_true
62
+ end
63
+ it "should not be able to read objects that are registered" do
64
+ registered_object = ModsAsset.new
65
+ @solr_resp.stub(:docs).and_return([{'read_access_group_t' =>['registered']}])
66
+ subject.can?(:read, registered_object).should_not be_true
67
+ end
68
+ end
69
+ context "for a signed in user" do
70
+ subject { Ability.new(stub("user", :email=>'archivist1@example.com', :new_record? => false, :is_being_superuser? =>false)) }
71
+ it "should be able to read objects that are public" do
72
+ public_object = ModsAsset.new
73
+ @solr_resp.stub(:docs).and_return([{'read_access_group_t' =>['public']}])
74
+ subject.can?(:read, public_object).should be_true
75
+ end
76
+ it "should be able to read objects that are registered" do
77
+ registered_object = ModsAsset.new
78
+ @solr_resp.stub(:docs).and_return([{'read_access_group_t' =>['registered']}])
79
+ subject.can?(:read, registered_object).should be_true
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,173 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require "nokogiri"
3
+
4
+ describe Hydra::Datastream::RightsMetadata do
5
+
6
+ before(:each) do
7
+ # The way RubyDora loads objects prevents us from stubbing the fedora connection :(
8
+ # ActiveFedora::RubydoraConnection.stubs(:instance).returns(stub_everything())
9
+ obj = ActiveFedora::Base.new
10
+ @sample = Hydra::Datastream::RightsMetadata.new(obj.inner_object, nil)
11
+ @sample.stub(:content).and_return('')
12
+ end
13
+
14
+ describe "permissions" do
15
+ describe "setter" do
16
+ it "should create/update/delete permissions for the given user/group" do
17
+ @sample.class.terminology.xpath_for(:access, :person, "person_123").should == '//oxns:access/oxns:machine/oxns:person[contains(., "person_123")]'
18
+
19
+ person_123_perms_xpath = @sample.class.terminology.xpath_for(:access, :person, "person_123")
20
+ group_zzz_perms_xpath = @sample.class.terminology.xpath_for(:access, :group, "group_zzz")
21
+
22
+ @sample.find_by_terms(person_123_perms_xpath).should be_empty
23
+ @sample.permissions({"person"=>"person_123"}, "edit").should == "edit"
24
+ @sample.permissions({"group"=>"group_zzz"}, "edit").should == "edit"
25
+
26
+ @sample.find_by_terms(person_123_perms_xpath).first.ancestors("access").first.attributes["type"].text.should == "edit"
27
+ @sample.find_by_terms(group_zzz_perms_xpath).first.ancestors("access").first.attributes["type"].text.should == "edit"
28
+
29
+ @sample.permissions({"person"=>"person_123"}, "read")
30
+ @sample.permissions({"group"=>"group_zzz"}, "read")
31
+ @sample.find_by_terms(person_123_perms_xpath).length.should == 1
32
+
33
+ @sample.find_by_terms(person_123_perms_xpath).first.ancestors("access").first.attributes["type"].text.should == "read"
34
+ @sample.find_by_terms(group_zzz_perms_xpath).first.ancestors("access").first.attributes["type"].text.should == "read"
35
+
36
+ @sample.permissions({"person"=>"person_123"}, "none").should == "none"
37
+ @sample.permissions({"group"=>"group_zzz"}, "none").should == "none"
38
+ @sample.find_by_terms(person_123_perms_xpath).should be_empty
39
+ @sample.find_by_terms(person_123_perms_xpath).should be_empty
40
+ end
41
+ it "should remove existing permissions (leaving only one permission level per user/group)" do
42
+ person_123_perms_xpath = @sample.class.terminology.xpath_for(:access, :person, "person_123")
43
+ group_zzz_perms_xpath = @sample.class.terminology.xpath_for(:access, :group, "group_zzz")
44
+
45
+ @sample.find_by_terms(person_123_perms_xpath).length.should == 0
46
+ @sample.find_by_terms(group_zzz_perms_xpath).length.should == 0
47
+ @sample.permissions({"person"=>"person_123"}, "read")
48
+ @sample.permissions({"group"=>"group_zzz"}, "read")
49
+ @sample.find_by_terms(person_123_perms_xpath).length.should == 1
50
+ @sample.find_by_terms(group_zzz_perms_xpath).length.should == 1
51
+
52
+ @sample.permissions({"person"=>"person_123"}, "edit")
53
+ @sample.permissions({"group"=>"group_zzz"}, "edit")
54
+ @sample.find_by_terms(person_123_perms_xpath).length.should == 1
55
+ @sample.find_by_terms(group_zzz_perms_xpath).length.should == 1
56
+ end
57
+ it "should not impact other users permissions" do
58
+ @sample.permissions({"person"=>"person_123"}, "read")
59
+ @sample.permissions({"person"=>"person_789"}, "edit")
60
+
61
+ @sample.permissions({"person"=>"person_123"}).should == "read"
62
+ @sample.permissions({"person"=>"person_456"}, "read")
63
+ @sample.permissions({"person"=>"person_123"}).should == "read"
64
+ @sample.permissions({"person"=>"person_456"}).should == "read"
65
+ @sample.permissions({"person"=>"person_789"}).should == "edit"
66
+
67
+
68
+ end
69
+ end
70
+ describe "getter" do
71
+ it "should return permissions level for the given user/group" do
72
+ @sample.permissions({"person"=>"person_123"}, "edit")
73
+ @sample.permissions({"group"=>"group_zzz"}, "discover")
74
+ @sample.permissions({"person"=>"person_123"}).should == "edit"
75
+ @sample.permissions({"group"=>"group_zzz"}).should == "discover"
76
+ @sample.permissions({"group"=>"foo_people"}).should == "none"
77
+ end
78
+ end
79
+ end
80
+ describe "groups" do
81
+ it "should return a hash of all groups with permissions set, along with their permission levels" do
82
+ @sample.permissions({"group"=>"group_zzz"}, "edit")
83
+ @sample.permissions({"group"=>"public"}, "discover")
84
+
85
+ #@sample.groups.should == {"group_zzz"=>"edit", "public"=>"discover"}
86
+ @sample.groups.should == {"public"=>"discover", "group_zzz"=>"edit"}
87
+ end
88
+ end
89
+ describe "individuals" do
90
+ it "should return a hash of all individuals with permissions set, along with their permission levels" do
91
+ @sample.permissions({"person"=>"person_123"}, "read")
92
+ @sample.permissions({"person"=>"person_456"}, "edit")
93
+ @sample.individuals.should == {"person_123"=>"read", "person_456"=>"edit"}
94
+ end
95
+ end
96
+
97
+ describe "update_permissions" do
98
+ it "should accept a hash of groups and persons, updating their permissions accordingly" do
99
+ @sample.should_receive(:permissions).with({"group" => "group1"}, "discover")
100
+ @sample.should_receive(:permissions).with({"group" => "group2"}, "edit")
101
+ @sample.should_receive(:permissions).with({"person" => "person1"}, "read")
102
+ @sample.should_receive(:permissions).with({"person" => "person2"}, "discover")
103
+
104
+ @sample.update_permissions( {"group"=>{"group1"=>"discover","group2"=>"edit"}, "person"=>{"person1"=>"read","person2"=>"discover"}} )
105
+ end
106
+ end
107
+
108
+ describe "update_indexed_attributes" do
109
+ it "should update the declared properties" do
110
+ @sample.find_by_terms(*[:edit_access, :person]).length.should == 0
111
+ @sample.update_values([:edit_access, :person]=>"user id").should == {"edit_access_person"=>{"0"=>"user id"}}
112
+ @sample.find_by_terms(*[:edit_access, :person]).length.should == 1
113
+ @sample.find_by_terms(*[:edit_access, :person]).first.text.should == "user id"
114
+ end
115
+ end
116
+ describe "to_solr" do
117
+ it "should populate solr doc with the correct fields" do
118
+ params = {[:edit_access, :person]=>"Lil Kim", [:edit_access, :group]=>["group1","group2"], [:discover_access, :group]=>["public"],[:discover_access, :person]=>["Joe Schmoe"]}
119
+ @sample.update_values(params)
120
+ solr_doc = @sample.to_solr
121
+
122
+ solr_doc["edit_access_person_t"].should == ["Lil Kim"]
123
+ solr_doc["edit_access_group_t"].sort.should == ["group1", "group2"]
124
+ solr_doc["discover_access_person_t"].should == ["Joe Schmoe"]
125
+ solr_doc["discover_access_group_t"].should == ["public"]
126
+ end
127
+ it "should solrize fixture content correctly" do
128
+ lsample = Hydra::Datastream::RightsMetadata.new(nil, nil)
129
+ lsample.update_permissions({'person' => {'researcher1' => 'edit'},
130
+ 'group' => {'archivist' => 'edit', 'public' =>'read', 'bob'=>'discover'}})
131
+
132
+ solr_doc = lsample.to_solr
133
+ solr_doc["edit_access_person_t"].should == ["researcher1"]
134
+ solr_doc["edit_access_group_t"].should == ["archivist"]
135
+ solr_doc["read_access_group_t"].should == ["public"]
136
+ solr_doc["discover_access_group_t"].should == ["bob"]
137
+ end
138
+ end
139
+ describe "embargo_release_date=" do
140
+ it "should update the appropriate node with the value passed" do
141
+ @sample.embargo_release_date=("2010-12-01")
142
+ @sample.embargo_release_date.should == "2010-12-01"
143
+ end
144
+ it "should only accept valid date values" do
145
+
146
+ end
147
+ end
148
+ describe "embargo_release_date" do
149
+ it "should return solr formatted date" do
150
+ @sample.embargo_release_date=("2010-12-01")
151
+ @sample.embargo_release_date(:format=>:solr_date).should == "2010-12-01T23:59:59Z"
152
+ end
153
+
154
+ # this test was returning '' under 1.9 and returning nil under ree and 1.8.7
155
+ it "should not return anything if the date is empty string" do
156
+ @sample.update_values({[:embargo,:machine,:date]=>''})
157
+ @sample.embargo_release_date(:format=>:solr_date).should be_blank
158
+ end
159
+ end
160
+ describe "under_embargo?" do
161
+ it "should return true if the current date is before the embargo release date" do
162
+ @sample.embargo_release_date=Date.today+1.month
163
+ @sample.under_embargo?.should be_true
164
+ end
165
+ it "should return false if the current date is after the embargo release date" do
166
+ @sample.embargo_release_date=Date.today-1.month
167
+ @sample.under_embargo?.should be_false
168
+ end
169
+ it "should return false if there is no embargo date" do
170
+ @sample.under_embargo?.should be_false
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe Hydra::ModelMixins::RightsMetadata do
4
+ subject { ModsAsset.new }
5
+ it "should have a set of permissions" do
6
+ subject.discover_groups=['group1', 'group2']
7
+ subject.edit_users=['user1']
8
+ subject.read_users=['user2', 'user3']
9
+ subject.permissions.should include({:type=>"group", :access=>"discover", :name=>"group1"},
10
+ {:type=>"group", :access=>"discover", :name=>"group2"},
11
+ {:type=>"user", :access=>"read", :name=>"user2"},
12
+ {:type=>"user", :access=>"read", :name=>"user3"},
13
+ {:type=>"user", :access=>"edit", :name=>"user1"})
14
+ end
15
+
16
+ describe "updating permissions" do
17
+ it "should create new group permissions" do
18
+ subject.permissions = [{:name=>'group1', :access=>'discover', :type=>'group'}]
19
+ subject.permissions.should == [{:type=>'group', :access=>'discover', :name=>'group1'}]
20
+ end
21
+ it "should create new user permissions" do
22
+ subject.permissions = [{:name=>'user1', :access=>'discover', :type=>'user'}]
23
+ subject.permissions.should == [{:type=>'user', :access=>'discover', :name=>'user1'}]
24
+ end
25
+ it "should not replace existing groups" do
26
+ subject.permissions = [{:name=>'group1', :access=>'discover', :type=>'group'}]
27
+ subject.permissions = [{:name=>'group2', :access=>'discover', :type=>'group'}]
28
+ subject.permissions.should == [{:type=>'group', :access=>'discover', :name=>'group1'},
29
+ {:type=>'group', :access=>'discover', :name=>'group2'}]
30
+ end
31
+ it "should not replace existing users" do
32
+ subject.permissions = [{:name=>'user1', :access=>'discover', :type=>'user'}]
33
+ subject.permissions = [{:name=>'user2', :access=>'discover', :type=>'user'}]
34
+ subject.permissions.should == [{:type=>'user', :access=>'discover', :name=>'user1'},
35
+ {:type=>'user', :access=>'discover', :name=>'user2'}]
36
+ end
37
+ it "should update permissions on existing users" do
38
+ subject.permissions = [{:name=>'user1', :access=>'discover', :type=>'user'}]
39
+ subject.permissions = [{:name=>'user1', :access=>'edit', :type=>'user'}]
40
+ subject.permissions.should == [{:type=>'user', :access=>'edit', :name=>'user1'}]
41
+ end
42
+ it "should update permissions on existing groups" do
43
+ subject.permissions = [{:name=>'group1', :access=>'discover', :type=>'group'}]
44
+ subject.permissions = [{:name=>'group1', :access=>'edit', :type=>'group'}]
45
+ subject.permissions.should == [{:type=>'group', :access=>'edit', :name=>'group1'}]
46
+ end
47
+
48
+ end
49
+
50
+ context "with rightsMetadata" do
51
+ before do
52
+ subject.rightsMetadata.update_permissions("person"=>{"person1"=>"read","person2"=>"discover"}, "group"=>{'group-6' => 'read', "group-7"=>'read', 'group-8'=>'edit'})
53
+ subject.save
54
+ end
55
+ it "should have read groups accessor" do
56
+ subject.read_groups.should == ['group-6', 'group-7']
57
+ end
58
+ it "should have read groups string accessor" do
59
+ subject.read_groups_string.should == 'group-6, group-7'
60
+ end
61
+ it "should have read groups writer" do
62
+ subject.read_groups = ['group-2', 'group-3']
63
+ subject.rightsMetadata.groups.should == {'group-2' => 'read', 'group-3'=>'read', 'group-8' => 'edit'}
64
+ subject.rightsMetadata.individuals.should == {"person1"=>"read","person2"=>"discover"}
65
+ end
66
+
67
+ it "should have read groups string writer" do
68
+ subject.read_groups_string = 'umg/up.dlt.staff, group-3'
69
+ subject.rightsMetadata.groups.should == {'umg/up.dlt.staff' => 'read', 'group-3'=>'read', 'group-8' => 'edit'}
70
+ subject.rightsMetadata.individuals.should == {"person1"=>"read","person2"=>"discover"}
71
+ end
72
+ it "should only revoke eligible groups" do
73
+ subject.set_read_groups(['group-2', 'group-3'], ['group-6'])
74
+ # 'group-7' is not eligible to be revoked
75
+ subject.rightsMetadata.groups.should == {'group-2' => 'read', 'group-3'=>'read', 'group-7' => 'read', 'group-8' => 'edit'}
76
+ subject.rightsMetadata.individuals.should == {"person1"=>"read","person2"=>"discover"}
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ describe RoleMapper do
4
+ before do
5
+ class Rails; end
6
+
7
+ Rails.stub(:root).and_return('spec/support')
8
+ Rails.stub(:env).and_return('test')
9
+ end
10
+
11
+ it "should define the 4 roles" do
12
+ RoleMapper.role_names.sort.should == %w(admin_policy_object_editor archivist donor patron researcher)
13
+ end
14
+ it "should quer[iy]able for roles for a given user" do
15
+ RoleMapper.roles('leland_himself@example.com').sort.should == ['archivist', 'donor', 'patron']
16
+ RoleMapper.roles('archivist2@example.com').should == ['archivist']
17
+ end
18
+
19
+ it "should return an empty array if there are no roles" do
20
+ RoleMapper.roles('zeus@olympus.mt').empty?.should == true
21
+ end
22
+ it "should know who is what" do
23
+ RoleMapper.whois('archivist').sort.should == %w(archivist1@example.com archivist2@example.com leland_himself@example.com)
24
+ RoleMapper.whois('salesman').empty?.should == true
25
+ RoleMapper.whois('admin_policy_object_editor').sort.should == %w(archivist1@example.com)
26
+ end
27
+
28
+ end