ddr-core 0.2.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.
- checksums.yaml +7 -0
- data/LICENSE.txt +12 -0
- data/README.md +27 -0
- data/Rakefile +30 -0
- data/app/assets/config/ddr_core_manifest.js +0 -0
- data/app/controllers/users/omniauth_callbacks_controller.rb +11 -0
- data/app/controllers/users/sessions_controller.rb +15 -0
- data/app/models/concerns/ddr/captionable.rb +25 -0
- data/app/models/concerns/ddr/describable.rb +108 -0
- data/app/models/concerns/ddr/governable.rb +25 -0
- data/app/models/concerns/ddr/has_admin_metadata.rb +141 -0
- data/app/models/concerns/ddr/has_attachments.rb +10 -0
- data/app/models/concerns/ddr/has_children.rb +10 -0
- data/app/models/concerns/ddr/has_content.rb +132 -0
- data/app/models/concerns/ddr/has_extracted_text.rb +10 -0
- data/app/models/concerns/ddr/has_intermediate_file.rb +25 -0
- data/app/models/concerns/ddr/has_multires_image.rb +14 -0
- data/app/models/concerns/ddr/has_parent.rb +18 -0
- data/app/models/concerns/ddr/has_struct_metadata.rb +21 -0
- data/app/models/concerns/ddr/has_thumbnail.rb +33 -0
- data/app/models/concerns/ddr/solr_document_behavior.rb +429 -0
- data/app/models/concerns/ddr/streamable.rb +25 -0
- data/app/models/ddr/admin_set.rb +28 -0
- data/app/models/ddr/attachment.rb +14 -0
- data/app/models/ddr/collection.rb +28 -0
- data/app/models/ddr/component.rb +31 -0
- data/app/models/ddr/contact.rb +23 -0
- data/app/models/ddr/digest.rb +8 -0
- data/app/models/ddr/file.rb +40 -0
- data/app/models/ddr/item.rb +36 -0
- data/app/models/ddr/language.rb +31 -0
- data/app/models/ddr/media_type.rb +22 -0
- data/app/models/ddr/resource.rb +94 -0
- data/app/models/ddr/rights_statement.rb +25 -0
- data/app/models/ddr/target.rb +17 -0
- data/config/initializers/devise.rb +262 -0
- data/config/locales/ddr-core.en.yml +85 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20141104181418_create_users.rb +34 -0
- data/db/migrate/20141107124012_add_columns_to_user.rb +46 -0
- data/lib/ddr-core.rb +1 -0
- data/lib/ddr/auth.rb +80 -0
- data/lib/ddr/auth/ability.rb +18 -0
- data/lib/ddr/auth/ability_definitions.rb +26 -0
- data/lib/ddr/auth/ability_definitions/admin_set_ability_definitions.rb +9 -0
- data/lib/ddr/auth/ability_definitions/alias_ability_definitions.rb +23 -0
- data/lib/ddr/auth/ability_definitions/attachment_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/collection_ability_definitions.rb +28 -0
- data/lib/ddr/auth/ability_definitions/component_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/item_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/lock_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +16 -0
- data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +39 -0
- data/lib/ddr/auth/ability_definitions/superuser_ability_definitions.rb +9 -0
- data/lib/ddr/auth/ability_factory.rb +10 -0
- data/lib/ddr/auth/abstract_ability.rb +48 -0
- data/lib/ddr/auth/affiliation.rb +14 -0
- data/lib/ddr/auth/affiliation_groups.rb +20 -0
- data/lib/ddr/auth/anonymous_ability.rb +7 -0
- data/lib/ddr/auth/auth_context.rb +109 -0
- data/lib/ddr/auth/auth_context_factory.rb +13 -0
- data/lib/ddr/auth/detached_auth_context.rb +19 -0
- data/lib/ddr/auth/dynamic_groups.rb +13 -0
- data/lib/ddr/auth/effective_permissions.rb +12 -0
- data/lib/ddr/auth/effective_roles.rb +9 -0
- data/lib/ddr/auth/failure_app.rb +16 -0
- data/lib/ddr/auth/group.rb +40 -0
- data/lib/ddr/auth/grouper_gateway.rb +70 -0
- data/lib/ddr/auth/groups.rb +32 -0
- data/lib/ddr/auth/ldap_gateway.rb +74 -0
- data/lib/ddr/auth/permissions.rb +18 -0
- data/lib/ddr/auth/remote_groups.rb +14 -0
- data/lib/ddr/auth/role_based_access_controls_enforcement.rb +56 -0
- data/lib/ddr/auth/roles.rb +28 -0
- data/lib/ddr/auth/roles/role.rb +121 -0
- data/lib/ddr/auth/roles/role_type.rb +23 -0
- data/lib/ddr/auth/roles/role_types.rb +52 -0
- data/lib/ddr/auth/superuser_ability.rb +7 -0
- data/lib/ddr/auth/test_helpers.rb +22 -0
- data/lib/ddr/auth/user.rb +54 -0
- data/lib/ddr/auth/web_auth_context.rb +29 -0
- data/lib/ddr/core.rb +110 -0
- data/lib/ddr/core/engine.rb +8 -0
- data/lib/ddr/core/version.rb +5 -0
- data/lib/ddr/error.rb +16 -0
- data/lib/ddr/files.rb +13 -0
- data/lib/ddr/fits.rb +189 -0
- data/lib/ddr/index.rb +29 -0
- data/lib/ddr/index/abstract_query_result.rb +22 -0
- data/lib/ddr/index/connection.rb +38 -0
- data/lib/ddr/index/csv_query_result.rb +84 -0
- data/lib/ddr/index/document_builder.rb +9 -0
- data/lib/ddr/index/field.rb +35 -0
- data/lib/ddr/index/field_attribute.rb +22 -0
- data/lib/ddr/index/fields.rb +154 -0
- data/lib/ddr/index/filter.rb +139 -0
- data/lib/ddr/index/query.rb +82 -0
- data/lib/ddr/index/query_builder.rb +185 -0
- data/lib/ddr/index/query_clause.rb +112 -0
- data/lib/ddr/index/query_params.rb +40 -0
- data/lib/ddr/index/query_result.rb +102 -0
- data/lib/ddr/index/response.rb +30 -0
- data/lib/ddr/index/sort_order.rb +28 -0
- data/lib/ddr/index/unique_key_field.rb +12 -0
- data/lib/ddr/managers.rb +9 -0
- data/lib/ddr/managers/manager.rb +13 -0
- data/lib/ddr/managers/technical_metadata_manager.rb +141 -0
- data/lib/ddr/structure.rb +188 -0
- data/lib/ddr/structures/agent.rb +49 -0
- data/lib/ddr/structures/component_type_term.rb +29 -0
- data/lib/ddr/structures/div.rb +64 -0
- data/lib/ddr/structures/f_locat.rb +54 -0
- data/lib/ddr/structures/file.rb +52 -0
- data/lib/ddr/structures/file_grp.rb +35 -0
- data/lib/ddr/structures/file_sec.rb +22 -0
- data/lib/ddr/structures/fptr.rb +31 -0
- data/lib/ddr/structures/mets_hdr.rb +37 -0
- data/lib/ddr/structures/mptr.rb +49 -0
- data/lib/ddr/structures/struct_map.rb +40 -0
- data/lib/ddr/utils.rb +185 -0
- data/lib/ddr/vocab.rb +22 -0
- data/lib/ddr/vocab/asset.rb +51 -0
- data/lib/ddr/vocab/contact.rb +9 -0
- data/lib/ddr/vocab/display.rb +9 -0
- data/lib/ddr/vocab/duke_terms.rb +13 -0
- data/lib/ddr/vocab/rdf_vocabulary_parser.rb +43 -0
- data/lib/ddr/vocab/roles.rb +25 -0
- data/lib/ddr/vocab/sources/duketerms.rdf +870 -0
- data/lib/ddr/vocab/vocabulary.rb +37 -0
- data/lib/ddr/workflow.rb +8 -0
- data/lib/tasks/ddr/core_tasks.rake +4 -0
- metadata +428 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require "net-ldap"
|
|
2
|
+
|
|
3
|
+
module Ddr::Auth
|
|
4
|
+
class LdapGateway
|
|
5
|
+
|
|
6
|
+
SCOPE = Net::LDAP::SearchScope_SingleLevel
|
|
7
|
+
|
|
8
|
+
class_attribute :attributes
|
|
9
|
+
self.attributes = [ "edupersonaffiliation", "ismemberof" ]
|
|
10
|
+
|
|
11
|
+
attr_reader :ldap
|
|
12
|
+
|
|
13
|
+
def self.find(user_key)
|
|
14
|
+
new.find(user_key)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def initialize
|
|
18
|
+
@ldap = Net::LDAP.new(config)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def find(user_key)
|
|
22
|
+
result_set = ldap.search find_params(user_key)
|
|
23
|
+
if result_set
|
|
24
|
+
Result.new result_set.first
|
|
25
|
+
else
|
|
26
|
+
raise ldap.get_operation_result.message
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class Result
|
|
31
|
+
attr_reader :result
|
|
32
|
+
|
|
33
|
+
def initialize(result)
|
|
34
|
+
@result = result
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def affiliation
|
|
38
|
+
result ? result[:edupersonaffiliation] : []
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def ismemberof
|
|
42
|
+
result ? result[:ismemberof] : []
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def find_params(user_key)
|
|
49
|
+
{ scope: SCOPE,
|
|
50
|
+
filter: filter(user_key),
|
|
51
|
+
size: 1,
|
|
52
|
+
attributes: attributes
|
|
53
|
+
}
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def filter(user_key)
|
|
57
|
+
Net::LDAP::Filter.eq("eduPersonPrincipalName", user_key)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def config
|
|
61
|
+
{ host: ENV["LDAP_HOST"],
|
|
62
|
+
port: ENV["LDAP_PORT"],
|
|
63
|
+
base: ENV["LDAP_BASE"],
|
|
64
|
+
auth:
|
|
65
|
+
{ method: :simple,
|
|
66
|
+
username: ENV["LDAP_USER"],
|
|
67
|
+
password: ENV["LDAP_PASSWORD"]
|
|
68
|
+
},
|
|
69
|
+
encryption: { method: :simple_tls }
|
|
70
|
+
}
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module Ddr::Auth
|
|
2
|
+
class Permissions
|
|
3
|
+
|
|
4
|
+
READ = :read
|
|
5
|
+
DOWNLOAD = :download
|
|
6
|
+
ADD_CHILDREN = :add_children
|
|
7
|
+
UPDATE = :update
|
|
8
|
+
REPLACE = :replace
|
|
9
|
+
ARRANGE = :arrange
|
|
10
|
+
PUBLISH = :publish
|
|
11
|
+
UNPUBLISH = :unpublish
|
|
12
|
+
AUDIT = :audit
|
|
13
|
+
GRANT = :grant
|
|
14
|
+
|
|
15
|
+
ALL = [ READ, DOWNLOAD, ADD_CHILDREN, UPDATE, REPLACE, ARRANGE, PUBLISH, UNPUBLISH, AUDIT, GRANT ]
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Ddr::Auth
|
|
2
|
+
class RemoteGroups
|
|
3
|
+
|
|
4
|
+
# @param auth_context [AuthContext]
|
|
5
|
+
# @return [Array<Group>]
|
|
6
|
+
def self.call(auth_context)
|
|
7
|
+
auth_context.ismemberof.map do |id|
|
|
8
|
+
Group.new id.sub(/\Aurn:mace:duke\.edu:groups/, "duke")
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module Ddr
|
|
2
|
+
module Auth
|
|
3
|
+
#
|
|
4
|
+
# Hydra controller mixin for role-based access control
|
|
5
|
+
#
|
|
6
|
+
# Overrides Hydra::AccessControlsEnforcement#gated_discovery_filters
|
|
7
|
+
# to apply role filters instead of permissions filters.
|
|
8
|
+
#
|
|
9
|
+
module RoleBasedAccessControlsEnforcement
|
|
10
|
+
|
|
11
|
+
def self.included(controller)
|
|
12
|
+
controller.delegate :authorized_to_act_as_superuser?, to: :current_ability
|
|
13
|
+
controller.helper_method :authorized_to_act_as_superuser?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def current_ability
|
|
17
|
+
@current_ability ||= AbilityFactory.call(current_user, request.env)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# List of URIs for policies on which any of the current user's agent has a role in policy scope
|
|
21
|
+
def policy_role_policies
|
|
22
|
+
@policy_role_policies ||= Array.new.tap do |uris|
|
|
23
|
+
filters = current_ability.agents.map do |agent|
|
|
24
|
+
"#{Ddr::Index::Fields::POLICY_ROLE}:\"#{agent}\""
|
|
25
|
+
end.join(" OR ")
|
|
26
|
+
query = "#{Ddr::Index::Fields::ACTIVE_FEDORA_MODEL}:Collection AND (#{filters})"
|
|
27
|
+
results = ActiveFedora::SolrService.query(query, rows: Collection.count, fl: Ddr::Index::Fields::INTERNAL_URI)
|
|
28
|
+
results.each_with_object(uris) { |r, memo| memo << r[Ddr::Index::Fields::INTERNAL_URI] }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def policy_role_filters
|
|
33
|
+
if policy_role_policies.present?
|
|
34
|
+
rels = policy_role_policies.map { |pid| [:is_governed_by, pid] }
|
|
35
|
+
ActiveFedora::SolrService.construct_query_for_rel(rels, "OR")
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def resource_role_filters
|
|
40
|
+
current_ability.agents.map do |agent|
|
|
41
|
+
ActiveFedora::SolrService.raw_query(Ddr::Index::Fields::RESOURCE_ROLE, agent)
|
|
42
|
+
end.join(" OR ")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def gated_discovery_filters
|
|
46
|
+
[resource_role_filters, policy_role_filters].compact
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Overrides Hydra::AccessControlsEnforcement
|
|
50
|
+
def enforce_show_permissions
|
|
51
|
+
authorize! :read, params[:id]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
module Ddr::Auth
|
|
2
|
+
module Roles
|
|
3
|
+
extend ActiveSupport::Autoload
|
|
4
|
+
|
|
5
|
+
autoload :Role
|
|
6
|
+
autoload :RoleType
|
|
7
|
+
autoload :RoleTypes
|
|
8
|
+
|
|
9
|
+
include RoleTypes
|
|
10
|
+
|
|
11
|
+
RESOURCE_SCOPE = "resource".freeze
|
|
12
|
+
POLICY_SCOPE = "policy".freeze
|
|
13
|
+
SCOPES = [RESOURCE_SCOPE, POLICY_SCOPE].freeze
|
|
14
|
+
|
|
15
|
+
class << self
|
|
16
|
+
|
|
17
|
+
def type_map
|
|
18
|
+
@type_map ||= role_types.map { |role_type| [role_type.to_s, role_type] }.to_h
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def role_types
|
|
22
|
+
@role_types ||= RoleTypes.constants(false).map { |const| RoleTypes.const_get(const) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
module Ddr
|
|
2
|
+
module Auth
|
|
3
|
+
module Roles
|
|
4
|
+
#
|
|
5
|
+
# The assignment of a role to an agent within a scope.
|
|
6
|
+
#
|
|
7
|
+
class Role < Valkyrie::Resource
|
|
8
|
+
|
|
9
|
+
DEFAULT_SCOPE = Roles::RESOURCE_SCOPE
|
|
10
|
+
|
|
11
|
+
ValidScope = Valkyrie::Types::Strict::String.enum(*(Roles::SCOPES))
|
|
12
|
+
ValidRoleType = Valkyrie::Types::Strict::String.enum(*(Roles::role_types.map(&:title)))
|
|
13
|
+
|
|
14
|
+
attribute :agent, Valkyrie::Types::Strict::String.constrained(min_size: 1)
|
|
15
|
+
attribute :role_type, ValidRoleType
|
|
16
|
+
attribute :scope, ValidScope
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
|
|
20
|
+
# Build a Role instance from hash attributes
|
|
21
|
+
# @param args [Hash] the attributes
|
|
22
|
+
# @return [Role] the role
|
|
23
|
+
# @example
|
|
24
|
+
# Role.build type: "Curator", agent: "bob", scope: "resource"
|
|
25
|
+
def build(args={})
|
|
26
|
+
new.tap do |role|
|
|
27
|
+
args[:role_type] ||= args.delete(:type)
|
|
28
|
+
args[:agent] ||= nil # Triggers a constraint error
|
|
29
|
+
args[:agent] = args[:agent].to_s # Coerce Ddr::Auth:Group to string
|
|
30
|
+
|
|
31
|
+
args.each do |attr, val|
|
|
32
|
+
role.set_value(attr, val)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
role.scope ||= DEFAULT_SCOPE
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
###############
|
|
40
|
+
# FIXME or remove serialization/deserialization
|
|
41
|
+
###############
|
|
42
|
+
#
|
|
43
|
+
# # Deserialize a Role from JSON
|
|
44
|
+
# # @param json [String] the JSON string
|
|
45
|
+
# # @return [Role] the role
|
|
46
|
+
# def from_json(json)
|
|
47
|
+
# build JSON.parse(json)
|
|
48
|
+
# end
|
|
49
|
+
|
|
50
|
+
# alias_method :deserialize, :from_json
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
#
|
|
55
|
+
# DELETEME
|
|
56
|
+
#
|
|
57
|
+
# def build_attributes(args={})
|
|
58
|
+
# # symbolize keys and stringify values
|
|
59
|
+
# attrs = args.each_with_object({}) do |(k, v), memo|
|
|
60
|
+
# memo[k.to_sym] = Array(v).first.to_s
|
|
61
|
+
# end
|
|
62
|
+
# # set default scope if necessary
|
|
63
|
+
# attrs[:scope] ||= DEFAULT_SCOPE
|
|
64
|
+
# # accept :type key for role_type attribute
|
|
65
|
+
# if attrs.key?(:type)
|
|
66
|
+
# attrs[:role_type] = attrs.delete(:type)
|
|
67
|
+
# end
|
|
68
|
+
# attrs
|
|
69
|
+
# end
|
|
70
|
+
|
|
71
|
+
end # class << self
|
|
72
|
+
|
|
73
|
+
# Roles are considered equal (==) if they
|
|
74
|
+
# are of the same type and have the same agent and scope.
|
|
75
|
+
# @param other [Object] the object of comparison
|
|
76
|
+
# @return [Boolean] the result
|
|
77
|
+
def ==(other)
|
|
78
|
+
self.class == other.class &&
|
|
79
|
+
role_type == other.role_type &&
|
|
80
|
+
scope == other.scope &&
|
|
81
|
+
agent == other.agent
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
alias_method :eql?, :==
|
|
85
|
+
|
|
86
|
+
def in_resource_scope?
|
|
87
|
+
scope == Roles::RESOURCE_SCOPE
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def in_policy_scope?
|
|
91
|
+
scope == Roles::POLICY_SCOPE
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def inspect
|
|
95
|
+
"#<#{self.class.name} role_type=#{role_type.inspect}, " \
|
|
96
|
+
"agent=#{agent.inspect}, scope=#{scope.inspect}>"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# TODO refactor up?
|
|
100
|
+
def proper_attributes
|
|
101
|
+
attributes.slice(self.class.fields - self.class.reserved_attributes)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
###############
|
|
105
|
+
# FIXME or remove serialization/deserialization
|
|
106
|
+
###############
|
|
107
|
+
#
|
|
108
|
+
# delegate :to_json, to: :proper_attributes
|
|
109
|
+
#
|
|
110
|
+
# alias_method :serialize, :to_json
|
|
111
|
+
|
|
112
|
+
# Returns the permissions associated with the role
|
|
113
|
+
# @return [Array<Symbol>] the permissions
|
|
114
|
+
def permissions
|
|
115
|
+
Roles.type_map[role_type].permissions
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Ddr
|
|
2
|
+
module Auth
|
|
3
|
+
module Roles
|
|
4
|
+
class RoleType
|
|
5
|
+
|
|
6
|
+
attr_reader :title, :description, :permissions
|
|
7
|
+
alias_method :label, :title
|
|
8
|
+
|
|
9
|
+
def initialize(title, description, permissions)
|
|
10
|
+
@title = title.freeze
|
|
11
|
+
@description = description.freeze
|
|
12
|
+
@permissions = permissions.freeze
|
|
13
|
+
freeze
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_s
|
|
17
|
+
title
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module Ddr
|
|
2
|
+
module Auth
|
|
3
|
+
module Roles
|
|
4
|
+
module RoleTypes
|
|
5
|
+
|
|
6
|
+
CURATOR = RoleType.new(
|
|
7
|
+
"Curator",
|
|
8
|
+
"The Curator role conveys responsibility for curating a resource " \
|
|
9
|
+
"and delegating responsibilities to other agents.",
|
|
10
|
+
Permissions::ALL
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
EDITOR = RoleType.new(
|
|
14
|
+
"Editor",
|
|
15
|
+
"The Editor role conveys reponsibility for managing the content, " \
|
|
16
|
+
"description and structural arrangement of a resource.",
|
|
17
|
+
[ Permissions::READ, Permissions::DOWNLOAD, Permissions::ADD_CHILDREN,
|
|
18
|
+
Permissions::UPDATE, Permissions::REPLACE, Permissions::ARRANGE ]
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
METADATA_EDITOR = RoleType.new(
|
|
22
|
+
"MetadataEditor",
|
|
23
|
+
"The Metadata Editor role conveys responsibility for " \
|
|
24
|
+
"managing the description of a resource.",
|
|
25
|
+
[ Permissions::READ, Permissions::DOWNLOAD, Permissions::UPDATE ]
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
CONTRIBUTOR = RoleType.new(
|
|
29
|
+
"Contributor",
|
|
30
|
+
"The Contributor role conveys responsibility for adding related " \
|
|
31
|
+
"resources to a resource, such as works to a collection.",
|
|
32
|
+
[ Permissions::READ, Permissions::ADD_CHILDREN ]
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
DOWNLOADER = RoleType.new(
|
|
36
|
+
"Downloader",
|
|
37
|
+
"The Downloader role conveys access to the \"master\" file " \
|
|
38
|
+
"(original content bitstream) of a resource.",
|
|
39
|
+
[ Permissions::READ, Permissions::DOWNLOAD ]
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
VIEWER = RoleType.new(
|
|
43
|
+
"Viewer",
|
|
44
|
+
"The Viewer role conveys access to the description and \"access\" " \
|
|
45
|
+
"files (e.g., derivative bitstreams) of a resource.",
|
|
46
|
+
[ Permissions::READ ]
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module Ddr
|
|
2
|
+
module Auth
|
|
3
|
+
module TestHelpers
|
|
4
|
+
|
|
5
|
+
class MockLdapGateway
|
|
6
|
+
def self.find(*args); new.find(*args); end
|
|
7
|
+
def find(user_key); Ddr::Auth::LdapGateway::Result.new(nil); end
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class MockGrouperGateway
|
|
11
|
+
def self.repository_groups(*args); new.repository_groups(*args); end
|
|
12
|
+
def repository_groups(raw = false); []; end
|
|
13
|
+
def self.user_groups(*args); new.user_groups(*args); end
|
|
14
|
+
def user_groups(user, raw = false); []; end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
Ddr::Auth.ldap_gateway = Ddr::Auth::TestHelpers::MockLdapGateway
|
|
22
|
+
Ddr::Auth.grouper_gateway = Ddr::Auth::TestHelpers::MockGrouperGateway
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
require 'devise'
|
|
2
|
+
|
|
3
|
+
module Ddr::Auth
|
|
4
|
+
module User
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
delegate :can, :can?, :cannot, :cannot?, to: :ability
|
|
9
|
+
|
|
10
|
+
validates_uniqueness_of :username, case_sensitive: false
|
|
11
|
+
validates_format_of :email, with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/
|
|
12
|
+
|
|
13
|
+
devise :database_authenticatable, :omniauthable, omniauth_providers: [:shibboleth]
|
|
14
|
+
|
|
15
|
+
class_attribute :user_key_attribute
|
|
16
|
+
self.user_key_attribute = Devise.authentication_keys.first
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module ClassMethods
|
|
20
|
+
def find_by_user_key(key)
|
|
21
|
+
send("find_by_#{user_key_attribute}", key)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def from_omniauth(auth)
|
|
25
|
+
user = find_by_user_key(auth.uid) ||
|
|
26
|
+
new(user_key_attribute => auth.uid, :password => Devise.friendly_token)
|
|
27
|
+
user.update!(email: auth.info.email,
|
|
28
|
+
display_name: auth.info.name,
|
|
29
|
+
first_name: auth.info.first_name,
|
|
30
|
+
last_name: auth.info.last_name,
|
|
31
|
+
nickname: auth.info.nickname)
|
|
32
|
+
user
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Copied from Hydra::User
|
|
37
|
+
def user_key
|
|
38
|
+
send(user_key_attribute)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def to_s
|
|
42
|
+
user_key
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def agent
|
|
46
|
+
user_key
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def ability
|
|
50
|
+
@ability ||= AbilityFactory.call(self)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
end
|