hydra-access-controls 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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