forked from alxp/islandora
-
Notifications
You must be signed in to change notification settings - Fork 0
/
SecurityClass.inc
203 lines (188 loc) · 8.68 KB
/
SecurityClass.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<?php
// $Id$
/*
* Created on 22-Oct-08
*
* To change the template for this generated file go to
* Window - Preferences - PHPeclipse - PHP - Code Templates
*/
class SecurityClass {
public static $SECURITY_CLASS_SECURITY_STREAM = 'POLICY';
function SecurityClass() {
module_load_include('inc', 'SecurityClass', '');
drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);
}
function canIngestHere($collection_pid) {
global $user;
module_load_include('inc', 'fedora_repository', 'ObjectHelper');
$objectHelper = new ObjectHelper();
// get the childsecurity policy from the collection.
$policyStream = $objectHelper->getStream($collection_pid, SECURITYCLASS :: $SECURITY_CLASS_SECURITY_STREAM, FALSE);
if ($policyStream == NULL) {
// no child policy stream so collection is wide open to anyone to ingest, that has the permission ingest in Drupal.
// maybe we should return FALSE here?? would be more secure.
return TRUE;
}
$allowedUsersAndRoles = $this->getAllowedUsersAndRoles($policyStream);
if (!$allowedUsersAndRoles) {
// error processing stream so don't let them ingest here.
return FALSE;
}
$allowedUsers = $allowedUsersAndRoles["users"];
$allowedRoles = $allowedUsersAndRoles["roles"];
foreach ($user->roles as $role) {
if (in_array($role, $allowedRoles)) {
return TRUE;
}
}
if (in_array($user->name, $allowedUsers)) {
return TRUE;
}
return FALSE;
}
//parses our simple xacml policies checking for users or roles that are allowed to ingest
function getAllowedUsersAndRoles($policyStream) {
$allowedRoles = array();
$allowedUsers = array();
$usersAndRoles = array();
try {
$xml = new SimpleXMLElement($policyStream);
}
catch (Exception $e) {
watchdog(t("Fedora_Repository"), t("No roles found in security policy, could not parse policy stream."), NULL, WATCHDOG_ERROR);
//we may not want to send this to the screen.
drupal_set_message(t('No roles found in security policy, could not parse policy stream: !message', array('!message' => $e->getMessage())), 'error');
return NULL;
}
$xml->registerXPathNamespace('default', 'urn:oasis:names:tc:xacml:1.0:policy');
$conditions = $xml->xpath("//default:Condition");
foreach ($conditions as $condition) {
$designator = $condition->Apply->SubjectAttributeDesignator;
if (empty($designator)) {//$disignator may be wrapped by an or
$designator=$condition->Apply->Apply->SubjectAttributeDesignator;
}
$attributeId = strip_tags($designator['AttributeId']);
if ($attributeId == "fedoraRole") {
foreach ($condition->Apply->Apply->AttributeValue as $attributeValue) {
$allowedRoles[] = strip_tags($attributeValue->asXML());
}
foreach ($condition->Apply->Apply->Apply->AttributeValue as $attributeValue) {
$allowedRoles[] = strip_tags($attributeValue->asXML());
}
}
if ($attributeId == "urn:fedora:names:fedora:2.1:subject:loginId") {
foreach ($condition->Apply->Apply->AttributeValue as $attributeValue) {
$allowedUsers[] = strip_tags($attributeValue->asXML());
}
foreach ($condition->Apply->Apply->Apply->AttributeValue as $attributeValue) {
$allowedUsers[] = strip_tags($attributeValue->asXML());
}
}
}
$usersAndRoles['users'] = $allowedUsers;
$usersAndRoles['roles'] = $allowedRoles;
return $usersAndRoles;
}
// When a user's profile is saved in drupal we will attempt to create a collection for them in Fedora
// this will be their personal space. In the IR it is editable by users with the same role in the VRE
// it probably would not be.
function createPersonalPolicy($user) {
$doc = new DOMDocument();
try {
$doc->load(drupal_get_path('module', 'Fedora_Repository') . '/policies/noObjectEditPolicy.xml');
}
catch (exception $e) {
watchdog(t("Fedora_Repository"), t("Problem loading policy file."), NULL, WATCHDOG_ERROR);
}
$conditions = $doc->getElementsByTagName('Condition');
foreach ($conditions as $condition) {
$designator = $condition->getElementsByTagName('SubjectAttributeDesignator');
foreach ($designator as $des) {
$attributeId = $des->getAttribute('AttributeId');
if ($attributeId == 'fedoraRole') {
$applies = $condition->getElementsByTagName('Apply');
foreach ($applies as $apply) {
$functionId = $apply->getAttribute('FunctionId');
if ($functionId == 'urn:oasis:names:tc:xacml:1.0:function:string-bag') {
foreach ($user->roles as $role) {
if (!($role == 'authenticated user' || $role == 'administrator')) { //don't want authenticated user included administrator already is included'
$newAttributeValue=$doc->createElement('AttributeValue', '<![CDATA['. $role . ']]>');
$newAttributeValue->setAttribute('DataType', 'http://www.w3.org/2001/XMLSchema#string');
// $newAttributeValue->setAttribute('MustBePresent', 'FALSE');
$apply->appendChild($newAttributeValue);
}
}
}
}
}
if ($attributeId == 'urn:fedora:names:fedora:2.1:subject:loginId') {
$applies = $condition->getElementsByTagName('Apply');
foreach ($applies as $apply) {
$functionId = $apply->getAttribute('FunctionId');
if ($functionId == 'urn:oasis:names:tc:xacml:1.0:function:string-bag') {
$newAttributeValue=$doc->createElement('AttributeValue', $user->name);
$newAttributeValue->setAttribute('DataType', 'http://www.w3.org/2001/XMLSchema#string');
//$newAttributeValue->setAttribute('MustBePresent', 'FALSE');
$apply->appendChild($newAttributeValue);
}
}
}
}
}
return $doc; //NULL; //$xml;
}
/**
* Add a list of allowed users and roles to the given policy stream and return it.
*
* @param string $policy_stream
* @param array $users_and_roles
* @return DOMDocument
*/
function set_allowed_users_and_roles(&$policy_stream, $users_and_roles) {
$allowed_roles = $users_and_roles['roles'];
$allowed_users = $users_and_roles['users'];
$dom = new DOMDocument();
$dom->loadXML($policy_stream);
$conditions = $dom->getElementsByTagName('Condition');
foreach ($conditions as $condition) {
$designator = $condition->getElementsByTagName('SubjectAttributeDesignator');
foreach ($designator as $des) {
$attributeId = $des->getAttribute('AttributeId');
if ($attributeId == 'fedoraRole') {
// $applies = $condition->getElementsByTagName('Apply');
$applies = $des->parentNode->getElementsByTagName('Apply');
foreach ($applies as $apply) {
$functionId = $apply->getAttribute('FunctionId');
if ($functionId == 'urn:oasis:names:tc:xacml:1.0:function:string-bag') {
foreach ($allowed_roles as $role) {
if (!($role == 'authenticated user' || $role == 'administrator')) { //don't want authenticated user included administrator already is included'
$newAttributeValue=$dom->createElement('AttributeValue', $role);
$newAttributeValue->setAttribute('DataType', 'http://www.w3.org/2001/XMLSchema#string');
//$newAttributeValue->setAttribute('MustBePresent', 'FALSE');
$apply->appendChild($newAttributeValue);
}
}
}
}
}
if ($attributeId == 'urn:fedora:names:fedora:2.1:subject:loginId') {
// $applies = $condition->getElementsByTagName('Apply');
$applies = $des->parentNode->getElementsByTagName('Apply');
foreach ($applies as $apply) {
$functionId = $apply->getAttribute('FunctionId');
if ($functionId == 'urn:oasis:names:tc:xacml:1.0:function:string-bag') {
foreach ( $allowed_users as $username ) {
$newAttributeValue=$dom->createElement('AttributeValue', $username );
$newAttributeValue->setAttribute('DataType', 'http://www.w3.org/2001/XMLSchema#string');
//$newAttributeValue->setAttribute('MustBePresent', 'FALSE');
$apply->appendChild($newAttributeValue);
}
}
}
}
}
}
// $this->collection_policy_stream = $dom->saveXML();
return $dom->saveXML();
}
}