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