Skip to content

Commit

Permalink
Feature: Add accessibility security to ontology metadata & content se…
Browse files Browse the repository at this point in the history
…arch results (#74)

* add ontology accessibility restriction  to ontology metadata search

* add ontology accessibility restriction  to ontology content search

* add search results accessibility security test
  • Loading branch information
syphax-bouazzouni authored Apr 24, 2024
1 parent 45b2a36 commit 0fada75
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 4 deletions.
32 changes: 28 additions & 4 deletions controllers/search_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,20 @@ class SearchController < ApplicationController
format = params.fetch("hasOntologyLanguage", "").split(',')
is_of_type = params.fetch("isOfType", "").split(',')
has_format = params.fetch("hasFormat", "").split(',')
visibility = params["visibility"]&.presence || "public"
visibility = params["visibility"]
show_views = params["show_views"] == 'true'
sort = params.fetch("sort", "score desc, ontology_name_sort asc, ontology_acronym_sort asc")
page, page_size = page_params

fq = [
'resource_model:"ontology_submission"',
'submissionStatus_txt:ERROR_* OR submissionStatus_txt:"RDF" OR submissionStatus_txt:"UPLOADED"',
"ontology_viewingRestriction_t:#{visibility}",
groups.map { |x| "ontology_group_txt:\"http://data.bioontology.org/groups/#{x.upcase}\"" }.join(' OR '),
categories.map { |x| "ontology_hasDomain_txt:\"http://data.bioontology.org/categories/#{x.upcase}\"" }.join(' OR '),
languages.map { |x| "naturalLanguage_txt:\"#{x.downcase}\"" }.join(' OR '),

Check warning on line 35 in controllers/search_controller.rb

View check run for this annotation

Codecov / codecov/patch

controllers/search_controller.rb#L35

Added line #L35 was not covered by tests
]

fq << "ontology_viewingRestriction_t:#{visibility}" unless visibility.blank?
fq << "!ontology_viewOf_t:*" unless show_views

fq << format.map { |x| "hasOntologyLanguage_t:\"http://data.bioontology.org/ontology_formats/#{x}\"" }.join(' OR ') unless format.blank?
Expand Down Expand Up @@ -75,7 +75,15 @@ class SearchController < ApplicationController
old_resource_id = acronyms_ids[acronym]
old_id = old_resource_id.split('/').last.to_i rescue 0

if acronym.blank? || old_id && id && (id <= old_id)
already_found = (old_id && id && (id <= old_id))
not_restricted = (doc["ontology_viewingRestriction_t"]&.eql?('public') || current_user&.admin?)
user_not_restricted = not_restricted ||
Array(doc["ontology_viewingRestriction_txt"]).any? {|u| u.split(' ').last == current_user&.username} ||

Check warning on line 81 in controllers/search_controller.rb

View check run for this annotation

Codecov / codecov/patch

controllers/search_controller.rb#L81

Added line #L81 was not covered by tests
Array(doc["ontology_acl_txt"]).any? {|u| u.split(' ').last == current_user&.username}

user_restricted = !user_not_restricted

if acronym.blank? || already_found || user_restricted
total_found -= 1
next
end
Expand All @@ -99,10 +107,26 @@ class SearchController < ApplicationController
get '/content' do
query = params[:query] || params[:q]
page, page_size = page_params

ontologies = params.fetch("ontologies", "").split(',')

unless current_user&.admin?
restricted_acronyms = restricted_ontologies_to_acronyms(params)
ontologies = ontologies.empty? ? restricted_acronyms : ontologies & restricted_acronyms
end


types = params.fetch("types", "").split(',')
qf = params.fetch("qf", "")

qf = [
"ontology_t^100 resource_id^10",
"http___www.w3.org_2004_02_skos_core_prefLabel_txt^30",
"http___www.w3.org_2004_02_skos_core_prefLabel_t^30",
"http___www.w3.org_2000_01_rdf-schema_label_txt^30",
"http___www.w3.org_2000_01_rdf-schema_label_t^30",
].join(' ') if qf.blank?

fq = []

fq << ontologies.map { |x| "ontology_t:\"#{x}\"" }.join(' OR ') unless ontologies.blank?
Expand All @@ -117,7 +141,7 @@ class SearchController < ApplicationController
docs = resp["response"]["docs"]


reply 200,page_object(docs, total_found)
reply 200, page_object(docs, total_found)
end
end

Expand Down
71 changes: 71 additions & 0 deletions test/controllers/test_search_models_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,77 @@ def test_collection_search
assert_equal 2, res['response']['numFound']
end

def test_search_security
count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({
process_submission: true,
process_options: { process_rdf: true, extract_metadata: false, generate_missing_labels: false},
acronym: "BROSEARCHTEST",
name: "BRO Search Test",
file_path: "./test/data/ontology_files/BRO_v3.2.owl",
ont_count: 1,
submission_count: 1,
ontology_type: "VALUE_SET_COLLECTION"
})

count, acronyms, mccl = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({
process_submission: true,
process_options: { process_rdf: true, extract_metadata: false, generate_missing_labels: false},
acronym: "MCCLSEARCHTEST",
name: "MCCL Search Test",
file_path: "./test/data/ontology_files/CellLine_OWL_BioPortal_v1.0.owl",
ont_count: 1,
submission_count: 1
})


subs = LinkedData::Models::OntologySubmission.all
subs.each do |s|
s.bring_remaining
s.index_all_data(Logger.new($stdout))
end


allowed_user = User.new({
username: "allowed",
email: "[email protected]",
password: "12345"
})
allowed_user.save

blocked_user = User.new({
username: "blocked",
email: "[email protected]",
password: "12345"
})
blocked_user.save

bro = bro.first
bro.bring_remaining
bro.acl = [allowed_user]
bro.viewingRestriction = "private"
bro.save

self.class.enable_security
get "/search/ontologies?query=#{bro.acronym}&apikey=#{blocked_user.apikey}"
response = MultiJson.load(last_response.body)["collection"]
assert_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)}

get "/search/ontologies/content?q=*Research_Lab_Management*&apikey=#{blocked_user.apikey}"
assert last_response.ok?
res = MultiJson.load(last_response.body)
assert_equal 0, res['totalCount']

get "/search/ontologies?query=#{bro.acronym}&apikey=#{allowed_user.apikey}"
response = MultiJson.load(last_response.body)["collection"]
refute_empty response.select{|x| x["ontology_acronym_text"].eql?(bro.acronym)}

get "/search/ontologies/content?q=*Research_Lab_Management*&apikey=#{allowed_user.apikey}"
assert last_response.ok?
res = MultiJson.load(last_response.body)
assert_equal 1, res['totalCount']

self.class.reset_security(false)
end

def test_ontology_metadata_search
count, acronyms, bro = LinkedData::SampleData::Ontology.create_ontologies_and_submissions({
Expand Down

0 comments on commit 0fada75

Please sign in to comment.