VIVO-692 Restrict LOD by Publish level, not by Display level

Create a new annotation for properties and classes, HiddenFromPublishBelowRoleLevelAnnot.
Provide the means to initialize these annotations, edit them, and display them in the verbose property display.
Create a Permission and some requested actions so the policies can decide which statements must be filtered out, based on the user's role.
Add unit tests and improve acceptance tests
This commit is contained in:
j2blake 2014-03-10 17:58:26 -04:00
parent 36087a25c0
commit c084a05832
5 changed files with 1338 additions and 23 deletions

File diff suppressed because it is too large Load diff

View file

@ -11,19 +11,54 @@ function TestLOD() {
this.uri = "lodFacultyMember";
function setupButtons() {
document.getElementById("RDFXML_button").onclick = function() {
<!-- Extension buttons -->
document.getElementById("RDFXML_EXTENSION_button").onclick = function() {
requestWithExtension(self.uri, "rdf");
}
document.getElementById("N3_EXTENSION_button").onclick = function() {
requestWithExtension(self.uri, "n3");
}
document.getElementById("TTL_EXTENSION_button").onclick = function() {
requestWithExtension(self.uri, "ttl");
}
document.getElementById("JSONLD_EXTENSION_button").onclick = function() {
requestWithExtension(self.uri, "jsonld");
}
<!-- Format buttons -->
document.getElementById("RDFXML_FORMAT_button").onclick = function() {
requestWithFormat(self.uri, "rdfxml");
}
document.getElementById("N3_FORMAT_button").onclick = function() {
requestWithFormat(self.uri, "n3");
}
document.getElementById("TTL_FORMAT_button").onclick = function() {
requestWithFormat(self.uri, "ttl");
}
document.getElementById("JSONLD_FORMAT_button").onclick = function() {
requestWithFormat(self.uri, "jsonld");
}
<!-- Accept header buttons -->
document.getElementById("RDFXML_HEADER_button").onclick = function() {
requestWithAcceptHeader(self.uri, "application/rdf+xml");
}
document.getElementById("N3_button").onclick = function() {
document.getElementById("N3_HEADER_button").onclick = function() {
requestWithAcceptHeader(self.uri, "text/n3");
}
document.getElementById("TTL_button").onclick = function() {
document.getElementById("TTL_HEADER_button").onclick = function() {
requestWithAcceptHeader(self.uri, "text/turtle");
}
document.getElementById("JSONLD_button").onclick = function() {
document.getElementById("JSONLD_HEADER_button").onclick = function() {
requestWithAcceptHeader(self.uri, "application/json");
}
<!-- Failure buttons -->
document.getElementById("BOGUS_URI_button").onclick = function() {
requestWithAcceptHeader(self.uri + "XX", "application/rdf+xml");
}
@ -37,40 +72,61 @@ function TestLOD() {
requestWithExtension(self.uri, "bogus");
}
document.getElementById("CLEAR_button").onclick = clearResult
document.getElementById("CLEAR_REQUEST_button").onclick = clearRequest
document.getElementById("CLEAR_RESPONSE_button").onclick = clearResult
}
function requestWithAcceptHeader(uri, mimetype) {
$.ajax({
var parms = {
url: "individual/" + uri,
headers: {Accept: mimetype},
dataType: "text",
complete: displayResult
});
};
displayRequest(parms);
$.ajax(parms);
}
function requestWithFormat(uri, format) {
$.ajax({
var parms = {
url: "individual/" + uri + "?format=" + format,
dataType: "text",
complete: displayResult
});
};
displayRequest(parms);
$.ajax(parms);
}
function requestWithExtension(uri, extension) {
$.ajax({
var parms = {
url: "individual/" + uri + "/" + uri + "." + extension,
dataType: "text",
complete: displayResult
});
};
displayRequest(parms);
$.ajax(parms);
}
function displayRequest(parms) {
clearRequest();
$("#requestUrl").text(parms.url);
if (parms.headers) {
$("#acceptHeader").text(parms.headers.Accept);
}
}
function displayResult(xhr, status) {
clearResult();
$("#responseCode").text(xhr.status);
$("#mimeType").text(getMimeType(xhr));
$("#responseText").text(xhr.responseText);
}
function clearRequest() {
$("#requestUrl").text("No URL");
$("#acceptHeader").text("No header");
}
function clearResult() {
$("#responseCode").text("000");
$("#mimeType").text("No type");
@ -95,21 +151,38 @@ $(document).ready(function() {
<h1>Test the Linked Open Data requests</h1>
<h3>Try various accept headers</h3>
<input type="submit" value="get RDFXML" id="RDFXML_button">
<input type="submit" value="get N3" id="N3_button">
<input type="submit" value="get TTL" id="TTL_button">
<input type="submit" value="get JSONLD" id="JSONLD_button">
<h3>Request by extension</h3>
<input type="submit" value="get RDFXML by extension" id="RDFXML_EXTENSION_button">
<input type="submit" value="get N3 by extension" id="N3_EXTENSION_button">
<input type="submit" value="get TTL by extension" id="TTL_EXTENSION_button">
<input type="submit" value="get JSONLD by extension" id="JSONLD_EXTENSION_button">
<h3>Try non-existent URI with RDFXML accept header</h3>
<h3>Request by format parameters</h3>
<input type="submit" value="get RDFXML by format parameter" id="RDFXML_FORMAT_button">
<input type="submit" value="get N3 by format parameter" id="N3_FORMAT_button">
<input type="submit" value="get TTL by format parameter" id="TTL_FORMAT_button">
<input type="submit" value="get JSONLD by format parameter" id="JSONLD_FORMAT_button">
<h3>Request by accept headers</h3>
<input type="submit" value="get RDFXML by accept header" id="RDFXML_HEADER_button">
<input type="submit" value="get N3 by accept header" id="N3_HEADER_button">
<input type="submit" value="get TTL by accept header" id="TTL_HEADER_button">
<input type="submit" value="get JSONLD by accept header" id="JSONLD_HEADER_button">
<h3>An assortment of failures</h3>
<input type="submit" value="get BOGUS Individual" id="BOGUS_URI_button">
<input type="submit" value="use BOGUS Accept header" id="BOGUS_ACCEPT_button">
<input type="submit" value="use BOGUS format" id="BOGUS_FORMAT_button">
<input type="submit" value="use BOGUS extension" id="BOGUS_EXTENSION_button">
<h3>Response data</h3>
<input type="submit" value="CLEAR response" id="CLEAR_button">
<h2>Request data</h2>
<input type="submit" value="CLEAR request" id="CLEAR_REQUEST_button">
<div>Request URL is <b><span id="requestUrl">No URL</span></b></div>
<div>Accept header is <b><span id="acceptHeader">No header</span></b></div>
<h2>Response data</h2>
<input type="submit" value="CLEAR response" id="CLEAR_RESPONSE_button">
<div>Response code is <b><span id="responseCode">000</span></b></div>
<div>MIME type is <b><span id="mimeType">No type</span></b></div>
<div>Text is:</div>
<div id="responseText" style="font-size:small;">No text</div>
<div><pre id="responseText" style="font-size:small;">No text</pre></div>

View file

@ -1,8 +1,6 @@
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> .
@prefix simplePermission: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#> .
@prefix displayByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.DisplayByRolePermission#> .
@prefix editByRole: <java:edu.cornell.mannlib.vitro.webapp.auth.permissions.EditByRolePermission#> .
auth:ADMIN
auth:hasPermission simplePermission:UseSparqlUpdateApi ;

View file

@ -0,0 +1,76 @@
=begin
go through the lines of the file.
If you find a line that matches
vitro:hiddenFromDisplayBelowRoleLevelAnnot
and followed by a line that matches
<http://vitro.mannlib.cornell.edu/ns/vitro/role#public> ;
--where "public" may be any string
Insert 2 lines after the second one, replacing Display by Publish on the first, and duplicating the second.
If you find a line that contains
vitro:hiddenFromDisplayBelowRoleLevelAnnot
and does not match it, or is not followed by a line that matches
<http://vitro.mannlib.cornell.edu/ns/vitro/role#public> ;
Issue a warning and continue.
=end
FILE_PATH = "../../rdf/tbox/firsttime/initialTBoxAnnotations.n3"
DISPLAY_URI = "vitro:hiddenFromDisplayBelowRoleLevelAnnot"
DISPLAY_LOCALNAME = "hiddenFromDisplayBelowRoleLevelAnnot"
def read_the_file()
@lines = File.readlines(FILE_PATH);
end
def scan_the_lines()
@lines.each_index do |i|
@line1 = @lines[i]
@line2 = @lines[i+1]
@index = i
if linesContainMatch()
replicateProperty()
else
checkForMismatch()
end
end
end
def linesContainMatch()
return false unless @line1.strip() == DISPLAY_URI
return false unless @line2
return false unless m = @line2.match(/<http:\/\/vitro\.mannlib\.cornell\.edu\/ns\/vitro\/role#(.*)>/)
@role = m[1]
end
def replicateProperty()
newline1 = @line1.gsub(/Display/, "Publish")
newline2 = @line2.gsub(/#.*>/, "##{@role}>")
@lines.insert(@index + 2, newline1, newline2)
end
def checkForMismatch()
return false unless @line1.strip() == DISPLAY_URI
if !@line2
puts "Found display property at end of file"
return
end
if !@line2.match(/^\s*<http:\/\/vitro\.mannlib\.cornell\.edu\/ns\/vitro\/role#(.*)>\s*;\s*$/)
puts "Found bogus clutter in the second line (#{@index}) '#{@line2}'"
return
end
end
def write_the_file()
f = File.new(FILE_PATH+"-modified", "w")
@lines.each() do |line|
f.write(line)
end
f.close()
end
read_the_file()
scan_the_lines()
write_the_file()

View file

@ -0,0 +1,78 @@
=begin
go through the lines of the file.
If you find a line that matches
vitro:hiddenFromDisplayBelowRoleLevelAnnot
and followed by a line that matches
<http://vitro.mannlib.cornell.edu/ns/vitro/role#public> ;
--where "public" may be any string
Insert 2 lines after the second one, replacing Display by Publish on the first, and duplicating the second.
If you find a line that contains
vitro:hiddenFromDisplayBelowRoleLevelAnnot
and does not match it, or is not followed by a line that matches
<http://vitro.mannlib.cornell.edu/ns/vitro/role#public> ;
Issue a warning and continue.
<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#hiddenFromDisplayBelowRoleLevelAnnot>
<http://vitro.mannlib.cornell.edu/ns/vitro/role#public> ;
=end
FILE_PATH = "/Users/jeb228/Documents/EclipseStuff/vivoWorkspace/vivoCornell/productMods/bjl23/ingest/weill/grants/submodels/vivo-tbox2.ttl"
DISPLAY_URI = "<http://vitro.mannlib.cornell.edu/ns/vitro/0.7#hiddenFromDisplayBelowRoleLevelAnnot>"
def read_the_file()
@lines = File.readlines(FILE_PATH);
end
def scan_the_lines()
@lines.each_index do |i|
@line1 = @lines[i]
@line2 = @lines[i+1]
@index = i
if linesContainMatch()
replicateProperty()
else
checkForMismatch()
end
end
end
def linesContainMatch()
return false unless @line1.strip() == DISPLAY_URI
return false unless @line2
return false unless m = @line2.match(/<http:\/\/vitro\.mannlib\.cornell\.edu\/ns\/vitro\/role#(.*)>/)
@role = m[1]
end
def replicateProperty()
newline1 = @line1.gsub(/Display/, "Publish")
newline2 = @line2.gsub(/#.*>/, "##{@role}>")
@lines.insert(@index + 2, newline1, newline2)
end
def checkForMismatch()
return false unless @line1.strip() == DISPLAY_URI
if !@line2
puts "Found display property at end of file"
return
end
if !@line2.match(/^\s*<http:\/\/vitro\.mannlib\.cornell\.edu\/ns\/vitro\/role#(.*)>\s*;\s*$/)
puts "Found bogus clutter in the second line (#{@index}) '#{@line2}'"
return
end
end
def write_the_file()
f = File.new(FILE_PATH+"-modified", "w")
@lines.each() do |line|
f.write(line)
end
f.close()
end
read_the_file()
scan_the_lines()
write_the_file()