Commit bb933534 authored by Robert Lyon's avatar Robert Lyon

Bug 1722861: Restricting use of institution tags

If we are not a member of the institution we shouldn't be able to use
the institution tag

Also, if we leave the institution, the references of institution tags we are using
should be turned into normal tags for us

behatnotneeded

Change-Id: I5e8eb270a995fd5b556c72707ead48b767e1f686
Signed-off-by: Robert Lyon's avatarRobert Lyon <robertl@catalyst.net.nz>
parent 7caf24a6
......@@ -275,7 +275,7 @@ if ($tagsarray = get_records_sql_array("SELECT t.tag, t.prefix, t.ownerid
FROM (
SELECT ut.tag, NULL AS prefix, 0 AS ownerid
FROM {tag} ut
WHERE resourcetype = ? AND resourceid = ? AND ownertype <> 'instituion'
WHERE resourcetype = ? AND resourceid = ? AND ownertype != 'instituion'
AND NOT tag " . db_ilike() . " 'lastinstitution:%'
UNION
SELECT it.tag, it.ownerid AS prefix, i.id AS ownerid
......@@ -628,16 +628,22 @@ function edituser_site_submit(Pieform $form, $values) {
if (empty($tag)) {
continue;
}
if ($tagid = get_field('tag', 'resourceid', 'resourcetype', 'institution', 'tag', $tag)) {
$tag = 'tagid_' . $tagid;
$tag = check_if_institution_tag($tag);
if (preg_match("/^lastinstitution\:(.*)/", $tag, $matches)) {
$ownertype = 'institution';
$ownerid = $matches[1];
}
else {
$ownertype = 'user';
$ownerid = $user->id;
}
insert_record(
'tag',
(object) array(
'resourcetype' => 'usr',
'resourceid' => $user->id,
'ownertype' => 'user',
'ownerid' => $user->id,
'ownertype' => $ownertype,
'ownerid' => $ownerid,
'tag' => $tag,
'ctime' => db_format_timestamp(time()),
'editedby' => $USER->get('id'),
......
......@@ -658,9 +658,7 @@ abstract class ArtefactType implements IArtefactType {
if (empty($tag)) {
continue;
}
if ($institutiontag = get_record('tag', 'tag', $tag, 'resourcetype', 'institution', 'ownertype', 'institution')) {
$tag = 'tagid_' . $institutiontag->id;
}
$tag = check_if_institution_tag($tag);
insert_record('tag',
(object) array(
'resourcetype' => 'artefact',
......
......@@ -757,9 +757,7 @@ class BlockInstance {
foreach ($this->tags as $tag) {
// truncate the tag before insert it into the database
$tag = substr($tag, 0, 128);
if ($institutiontag = get_record('tag', 'tag', $tag, 'resourcetype', 'institution', 'ownertype', 'institution')) {
$tag = 'tagid_' . $institutiontag->id;
}
$tag = check_if_institution_tag($tag);
insert_record('tag',
(object)array(
'resourcetype' => 'blocktype',
......
......@@ -214,9 +214,7 @@ class Collection {
foreach ($tags as $tag) {
//truncate the tag before insert it into the database
$tag = substr($tag, 0, 128);
if ($institutiontag = get_record('tag', 'tag', $tag, 'resourcetype', 'institution', 'ownertype', 'institution')) {
$tag = 'tagid_' . $institutiontag->id;
}
$tag = check_if_institution_tag($tag);
insert_record('tag',
(object)array(
'resourcetype' => 'collection',
......
......@@ -41,11 +41,22 @@ function translate_tags_to_names(array $ids) {
global $USER;
// for an empty list, the element '' is transmitted
$ids = array_diff($ids, array(''));
$ids = array_map(function($a) {
if (strpos($a, ':')) {
$arr = explode(': ', $a);
return $arr[1];
$institutions = $USER->get('institutions');
if (!empty($institutions)) {
$institutions = array_keys($institutions);
// Fetch valid institution tags
$validinstitutiontags = get_column_sql("SELECT tag FROM {tag}
WHERE ownertype = 'institution' AND ownerid IN ('" . join("','", $institutions) . "')");
}
else {
$validinstitutiontags = array();
}
$ids = array_map(function($a) use ($validinstitutiontags) {
if (strpos($a, ': ')) {
if (in_array($a, $validinstitutiontags)) {
$arr = explode(': ', $a);
return trim($arr[1]);
}
}
return $a;
}, $ids);
......@@ -94,25 +105,14 @@ function get_all_tags_for_user($query = null, $limit = null, $offset = null) {
$usertags = "";
$userid = $USER->get('id');
$typecast = is_postgres() ? '::varchar' : '';
if ($USER->get('admin')) {
$usertags = "
UNION ALL
SELECT tag, COUNT(*) AS count, 'lastinstitution' AS prefix FROM {tag} t INNER JOIN {usr} u ON (t.resourcetype = 'usr' AND t.resourceid = u.id" . $typecast . ") GROUP BY 1";
}
else if ($admininstitutions = $USER->get('admininstitutions')) {
$insql = "'" . join("','", $admininstitutions) . "'";
$usertags = "
UNION ALL
SELECT tag, COUNT(*) AS count, 'lastinstitution' AS prefix FROM {tag} t INNER JOIN {usr} u ON (t.resourcetype = 'usr' AND t.resourceid = u.id" . $typecast . ") INNER JOIN {usr_institution} ui ON ui.usr=u.id WHERE ui.institution IN ($insql) GROUP BY 1";
}
$values = array($userid, $userid);
$querystr = '';
if ($query) {
$querystr = " WHERE tag LIKE '%' || ? || '%'";
$querystr = " WHERE tag " . db_ilike() . " '%' || ? || '%'";
$values[] = $query;
// Also do matching by institution name so we can list valid institution tags
// if we only know institution name
$querystr .= " OR prefix LIKE '%' || ? || '%'";
$querystr .= " OR prefix " . db_ilike() . " '%' || ? || '%'";
$values[] = $query;
}
$sql = "
......@@ -133,7 +133,7 @@ function get_all_tags_for_user($query = null, $limit = null, $offset = null) {
FROM {tag} t
JOIN {institution} i ON i.name = t.ownerid AND i.tags = 1
JOIN {usr_institution} ui ON ui.institution = i.name AND ui.usr = ?
" . $usertags . "
WHERE t.resourcetype != 'usr'
) tags
" . $querystr . "
GROUP BY tag, prefix
......
......@@ -622,6 +622,8 @@ class Institution {
}
public function removeMember($user) {
global $USER;
if (is_numeric($user)) {
$user = get_record('usr', 'id', $user);
}
......@@ -695,6 +697,20 @@ class Institution {
)
);
// Need to change any user's "institution tag" tags for this institution
// into normal user tags
$typecast = is_postgres() ? '::varchar' : '';
if ($userinstitutiontags = get_records_sql_array("
SELECT t.id, t.tag, (SELECT t2.tag FROM {tag} t2 WHERE t2.id" . $typecast . " = SUBSTRING(t.tag, 7)) AS realtag
FROM {tag} t
WHERE ownertype = ? AND ownerid = ?
AND tag LIKE 'tagid_%'", array('user', $user->id))) {
foreach ($userinstitutiontags as $newtag) {
execute_sql("UPDATE {tag} SET tag = ? WHERE id = ?", array($newtag->realtag, $newtag->id));
}
}
// If the user's license default is set to "institution default", remove the pref
delete_records('usr_account_preference', 'usr', $user->id, 'field', 'licensedefault', 'value', LICENSE_INSTITUTION_DEFAULT);
......
......@@ -4701,6 +4701,31 @@ function generate_csv($data, $csvfields, $csvheaders = array()) {
return $csv;
}
/**
*
*/
function check_if_institution_tag($tag) {
global $USER;
$institutions = $USER->get('institutions');
if ($institutions && $institutiontags = get_records_sql_array("
SELECT id FROM {tag}
WHERE tag = ?
AND resourcetype = ?
AND ownertype = ?
AND ownerid IN ('" . join("','", array_keys($institutions)) . "')
UNION
SELECT t.id FROM {tag} t
JOIN {institution} i ON i.name = t.ownerid
WHERE resourcetype = ?
AND ownertype = ?
AND ownerid IN ('" . join("','", array_keys($institutions)) . "')
AND CONCAT(i.displayname, ': ', t.tag) = ?",
array($tag, 'institution', 'institution', 'institution', 'institution', $tag))) {
$tag = 'tagid_' . $institutiontags[0]->id; // if same tag in multiple institutions just pick first
}
return $tag;
}
/**
* Check to make sure table is case sensitive (currently only for MySql)
* If it is not then reduce supplied array to a case insensitive version
......
......@@ -869,9 +869,7 @@ class View {
foreach ($this->get_tags() as $tag) {
//truncate the tag before insert it into the database
$tag = substr($tag, 0, 128);
if ($institutiontag = get_record('tag', 'tag', $tag, 'resourcetype', 'institution', 'ownertype', 'institution')) {
$tag = 'tagid_' . $institutiontag->id;
}
$tag = check_if_institution_tag($tag);
insert_record('tag',
(object)array(
'resourcetype' => 'view',
......
......@@ -1044,11 +1044,13 @@ class PluginSearchInternal extends PluginSearch {
$split = explode(':', $tag);
if (count($split) == 2) {
$prefix = trim($split[0]);
$tag = trim($split[1]);
$tag = get_field_sql("SELECT CONCAT('tagid_', t.id)
FROM {tag} t
JOIN {institution} i ON i.name = t.ownerid
WHERE i.displayname = ? AND t.tag = ?", array($prefix, $tag));
$itag = trim($split[1]);
if ($checktag = get_field_sql("SELECT CONCAT('tagid_', t.id)
FROM {tag} t
JOIN {institution} i ON i.name = t.ownerid
WHERE i.displayname = ? AND t.tag = ?", array($prefix, $itag))) {
$tag = $checktag;
}
}
$values = array($owner->id, $tag, $owner->id, $tag, $owner->id, $tag, $tag, $owner->id, $tag);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment