summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrautenberg <rautenberg@in-silico.ch>2016-09-06 12:33:22 +0200
committerrautenberg <rautenberg@in-silico.ch>2016-09-06 12:33:22 +0200
commit4e173fe7a205907fe77a741c3d30a75de285b211 (patch)
tree457ecb17bcc19102cace9d840f83f2820901c0fa
parent8220c743b1ed446e9fd857c783375bbc094b60a5 (diff)
clean code , add minimal authorization and authentication
-rw-r--r--VERSION2
-rw-r--r--api/api.json95
-rw-r--r--lib/aa.rb82
-rw-r--r--lib/compound.rb20
-rw-r--r--lib/dataset.rb2
-rw-r--r--lib/model.rb6
-rw-r--r--lib/validation.rb16
-rw-r--r--test/compound.rb2
8 files changed, 189 insertions, 36 deletions
diff --git a/VERSION b/VERSION
index 8a9ecc2..4e379d2 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.0.1 \ No newline at end of file
+0.0.2
diff --git a/api/api.json b/api/api.json
index e30ff98..4cd07c7 100644
--- a/api/api.json
+++ b/api/api.json
@@ -14,7 +14,7 @@
"url": "https://github.com/opentox/lazar-rest/blob/master/LICENSE"
}
},
- "host": "mr-test.in-silico.ch",
+ "host": "enm.in-silico.ch",
"basePath": "/",
"schemes": [
"https"
@@ -720,7 +720,7 @@
"descriptor"
],
"summary": "Descriptor calculation",
- "description": "Calculate descriptors for a single compound as SMILES string or a CSV compound file <br> <strong>curl example:</strong> <pre>curl -Lk -X POST -i -H \"accept:application/json\" -F \"file=@../lazar/test/data/batch_prediction.csv;type=application/csv\" -F \"descriptor=Openbabel.HBA1,Openbabel.HBA2,JoeLib.LogP\" https://mr-test.in-silico.ch/algorithm/descriptor curl -Lk -X POST -i -H \"accept:application/json\" -F \"identifier=O=C1NC(=O)NC=C1\" -F \"descriptor=Openbabel.MW,JoeLib.LogP\" https://mr-test.in-silico.ch/algorithm/descriptor </pre> CSV compound file has to be comma separated with SMILES strings in the first column.",
+ "description": "Calculate descriptors for a single compound as SMILES string <br> <strong>curl example:</strong> <pre>curl -Lk -X POST -i -H \"accept:application/json\" -F \"identifier=O=C1NC(=O)NC=C1\" -F \"descriptor=Openbabel.MW,JoeLib.LogP\" https://enm.in-silico.ch/compound/descriptor </pre>.",
"parameters": [
{
"name": "accept",
@@ -734,17 +734,10 @@
]
},
{
- "name": "file",
- "in": "formData",
- "description": "CSV file of compounds",
- "required": false,
- "type": "file"
- },
- {
"name": "identifier",
"in": "formData",
"description": "SMILES identifier",
- "required": false,
+ "required": true,
"type": "string"
},
{
@@ -900,6 +893,84 @@
}
}
}
+ },
+ "/aa/authenticate": {
+ "post": {
+ "tags": [
+ "authentication"
+ ],
+ "description": "Authentication against OpenSSO. Returns token. Requires Username and Password.",
+ "operationId": "login",
+ "consumes": [
+ "text/plain"
+ ],
+ "produces": [
+ "text/plain"
+ ],
+ "parameters": [
+ {
+ "in": "formData",
+ "name": "username",
+ "description": "username",
+ "required": true,
+ "type": "string"
+ },
+ {
+ "in": "formData",
+ "name": "password",
+ "description": "password",
+ "required": true,
+ "type": "string",
+ "format": "password"
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/200"
+ },
+ "400": {
+ "$ref": "#/responses/400"
+ },
+ "401": {
+ "$ref": "#/responses/401"
+ }
+ }
+ }
+ },
+ "/aa/logout": {
+ "post": {
+ "description": "Devalidates a token. Requires Subjectid.",
+ "operationId": "logout",
+ "tags": [
+ "authentication"
+ ],
+ "consumes": [
+ "text/plain"
+ ],
+ "produces": [
+ "text/plain"
+ ],
+ "parameters": [
+ {
+ "in": "formData",
+ "name": "subjectid",
+ "description": "subjectid",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/200"
+ },
+ "400": {
+ "$ref": "#/responses/400"
+ },
+ "401": {
+ "$ref": "#/responses/401"
+ }
+ }
+ }
}
},
"parameters": {
@@ -955,6 +1026,10 @@
"description": "Swagger API representation in JSON"
},
{
+ "name": "authentication",
+ "description": "minimal Authentication service"
+ },
+ {
"name": "descriptor",
"description": "Descriptor"
},
diff --git a/lib/aa.rb b/lib/aa.rb
new file mode 100644
index 0000000..6dfec4b
--- /dev/null
+++ b/lib/aa.rb
@@ -0,0 +1,82 @@
+post "/aa/authenticate/?" do
+ mime_types = ["text/plain"]
+ bad_request_error "Mime type #{@accept} not supported here. Please request data as #{mime_types.join(', ')}." unless mime_types.include? @accept
+ bad_request_error "Please send formdata username." unless params[:username]
+ bad_request_error "Please send formdata password." unless params[:password]
+ case @accept
+ when "text/plain"
+ if OpenTox::Authorization.authenticate(params[:username], params[:password])
+ return OpenTox::RestClientWrapper.subjectid
+ else
+ return nil
+ end
+ else
+ bad_request_error "'#{@accept}' is not a supported content type."
+ end
+end
+
+post "/aa/logout/?" do
+ mime_types = ["text/plain"]
+ bad_request_error "Mime type #{@accept} not supported here. Please request data as #{mime_types.join(', ')}." unless mime_types.include? @accept
+ bad_request_error "Please send formdata subjectid." unless params[:subjectid]
+ case @accept
+ when "text/plain"
+ if OpenTox::Authorization.logout(params[:subjectid])
+ return "Successfully logged out. \n"
+ else
+ return "Logout failed.\n"
+ end
+ else
+ bad_request_error "'#{@accept}' is not a supported content type."
+ end
+end
+
+module OpenTox
+
+ AA = "https://opensso.in-silico.ch"
+
+ module Authorization
+ #Authentication against OpenSSO. Returns token. Requires Username and Password.
+ # @param user [String] Username
+ # @param pw [String] Password
+ # @return [Boolean] true if successful
+ def self.authenticate(user, pw)
+ begin
+ res = RestClientWrapper.post("#{AA}/auth/authenticate",{:username=>user, :password => pw},{:subjectid => ""}).sub("token.id=","").sub("\n","")
+ if is_token_valid(res)
+ RestClientWrapper.subjectid = res
+ return true
+ else
+ bad_request_error "Authentication failed #{res.inspect}"
+ end
+ rescue
+ bad_request_error "Authentication failed #{res.inspect}"
+ end
+ end
+
+ #Logout on opensso. Make token invalid. Requires token
+ # @param [String] subjectid the subjectid
+ # @return [Boolean] true if logout is OK
+ def self.logout(subjectid=RestClientWrapper.subjectid)
+ begin
+ out = RestClientWrapper.post("#{AA}/auth/logout", :subjectid => subjectid)
+ return true unless is_token_valid(subjectid)
+ rescue
+ return false
+ end
+ return false
+ end
+
+ #Checks if a token is a valid token
+ # @param [String]subjectid subjectid from openSSO session
+ # @return [Boolean] subjectid is valid or not.
+ def self.is_token_valid(subjectid=RestClientWrapper.subjectid)
+ begin
+ return true if RestClientWrapper.post("#{AA}/auth/isTokenValid",:tokenid => subjectid) == "boolean=true\n"
+ rescue #do rescue because openSSO throws 401
+ return false
+ end
+ return false
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/compound.rb b/lib/compound.rb
index fc4ec55..c8dd98c 100644
--- a/lib/compound.rb
+++ b/lib/compound.rb
@@ -5,23 +5,19 @@
get "/compound/descriptor/?:descriptor?" do
case @accept
when "application/json"
- return "#{JSON.pretty_generate OpenTox::PhysChem::DESCRIPTORS} " unless params[:descriptor]
- return {params[:descriptor] => OpenTox::PhysChem::DESCRIPTORS[params[:descriptor]]}.to_json
+ return "#{JSON.pretty_generate PhysChem::DESCRIPTORS} " unless params[:descriptor]
+ return {params[:descriptor] => PhysChem::DESCRIPTORS[params[:descriptor]]}.to_json
else
- return OpenTox::PhysChem::DESCRIPTORS.collect{|k, v| "#{k}: #{v}\n"} unless params[:descriptor]
- return OpenTox::PhysChem::DESCRIPTORS[params[:descriptor]]
+ return PhysChem::DESCRIPTORS.collect{|k, v| "#{k}: #{v}\n"} unless params[:descriptor]
+ return PhysChem::DESCRIPTORS[params[:descriptor]]
end
end
post "/compound/descriptor/?" do
- bad_request_error "Missing Parameter " unless (params[:identifier] or params[:file]) and params[:descriptor]
+ bad_request_error "Missing Parameter " unless params[:identifier] && params[:descriptor]
descriptor = params['descriptor'].split(',')
- if params[:file]
- data = OpenTox::Dataset.from_csv_file params[:file][:tempfile]
- else
- data = OpenTox::Compound.from_smiles params[:identifier]
- end
- d = Algorithm::Descriptor.physchem data, descriptor
+ compound = Compound.from_smiles params[:identifier]
+ d = compound.physchem descriptor
csv = d.to_csv
csv = "SMILES,#{params[:descriptor]}\n#{params[:identifier]},#{csv}" if params[:identifier]
case @accept
@@ -37,7 +33,7 @@ end
get %r{/compound/(.+)} do |inchi|
bad_request_error "Input parameter #{inchi} is not an InChI" unless inchi.match(/^InChI=/)
- compound = OpenTox::Compound.from_inchi URI.unescape(inchi)
+ compound = Compound.from_inchi URI.unescape(inchi)
response['Content-Type'] = @accept
case @accept
when "application/json"
diff --git a/lib/dataset.rb b/lib/dataset.rb
index 56f510f..ff16640 100644
--- a/lib/dataset.rb
+++ b/lib/dataset.rb
@@ -1,6 +1,6 @@
# Get all datasets
get "/dataset/?" do
- datasets = OpenTox::Dataset.all
+ datasets = Dataset.all
case @accept
when "text/uri-list"
uri_list = datasets.collect{|dataset| uri("/dataset/#{dataset.id}")}
diff --git a/lib/model.rb b/lib/model.rb
index 6188cce..db0c190 100644
--- a/lib/model.rb
+++ b/lib/model.rb
@@ -3,7 +3,7 @@
# @param [Header] Accept one of text/uri-list,
# @return [text/uri-list] list of all prediction models
get "/model/?" do
- models = OpenTox::Model::Prediction.all
+ models = Model::Prediction.all
case @accept
when "text/uri-list"
uri_list = models.collect{|model| uri("/model/#{model.model_id}")}
@@ -21,7 +21,7 @@ get "/model/?" do
end
get "/model/:id/?" do
- model = OpenTox::Model::Lazar.find params[:id]
+ model = Model::Lazar.find params[:id]
resource_not_found_error "Model with id: #{params[:id]} not found." unless model
model[:URI] = uri("/model/#{model.id}")
model[:neighbor_algorithm_parameters][:feature_dataset_uri] = uri("/dataset/#{model[:neighbor_algorithm_parameters][:feature_dataset_id]}") if model[:neighbor_algorithm_parameters][:feature_dataset_id]
@@ -40,7 +40,7 @@ post "/model/:id/?" do
@error_report = "Attention, '#{params[:identifier]}' is not a valid SMILES string."
return @error_report
end
- model = OpenTox::Model::Lazar.find params[:id]
+ model = Model::Lazar.find params[:id]
batch = {}
compounds.each do |compound|
prediction = model.predict(compound)
diff --git a/lib/validation.rb b/lib/validation.rb
index 5963c63..ce31c34 100644
--- a/lib/validation.rb
+++ b/lib/validation.rb
@@ -24,13 +24,13 @@ get "/validation/:validationtype/?" do
bad_request_error "There is no such validation type as: #{params[:validationtype]}" unless VALIDATION_TYPES.include? params[:validationtype]
case params[:validationtype]
when "repeatedcrossvalidation"
- validations = OpenTox::Validation::RepeatedCrossValidation.all
+ validations = Validation::RepeatedCrossValidation.all
when "leaveoneout"
- validations = OpenTox::Validation::LeaveOneOut.all
+ validations = Validation::LeaveOneOut.all
when "crossvalidation"
- validations = OpenTox::Validation::CrossValidation.all
+ validations = Validation::CrossValidation.all
when "regressioncrossvalidation"
- validations = OpenTox::Validation::RegressionCrossValidation.all
+ validations = Validation::RegressionCrossValidation.all
end
case @accept
@@ -53,13 +53,13 @@ get "/validation/:validationtype/:id/?" do
bad_request_error "There is no such validation type as: #{params[:validationtype]}" unless VALIDATION_TYPES.include? params[:validationtype]
case params[:validationtype]
when "repeatedcrossvalidation"
- validation = OpenTox::Validation::RepeatedCrossValidation.find params[:id]
+ validation = Validation::RepeatedCrossValidation.find params[:id]
when "leaveoneout"
- validation = OpenTox::Validation::LeaveOneOut.find params[:id]
+ validation = Validation::LeaveOneOut.find params[:id]
when "crossvalidation"
- validation = OpenTox::Validation::CrossValidation.find params[:id]
+ validation = Validation::CrossValidation.find params[:id]
when "regressioncrossvalidation"
- validation = OpenTox::Validation::RegressionCrossValidation.find params[:id]
+ validation = Validation::RegressionCrossValidation.find params[:id]
end
resource_not_found_error "#{params[:validationtype]} with id: #{params[:id]} not found." unless validation
diff --git a/test/compound.rb b/test/compound.rb
index 5fac83d..cacd292 100644
--- a/test/compound.rb
+++ b/test/compound.rb
@@ -39,7 +39,7 @@ class CompoundTest < MiniTest::Test
res = RestClientWrapper.get File.join($compound_uri, $compound[0]), {}, {:accept => "application/json"}
assert_equal res.code, 200
js = JSON.parse res
- assert_equal js["chemblid"], "CHEMBL581676"
+ assert_equal js["chemblid"], "CHEMBL277500"
assert_equal js["names"].first, "BENZENE"
assert_equal js["names"][6], "71-43-2"
end