summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/authorization.rb92
-rw-r--r--lib/helper.rb27
-rw-r--r--lib/rest_client_wrapper.rb3
-rw-r--r--lib/task.rb10
-rw-r--r--lib/templates/config.yaml38
-rw-r--r--lib/validation.rb4
6 files changed, 103 insertions, 71 deletions
diff --git a/lib/authorization.rb b/lib/authorization.rb
index dd7dc12..1942e95 100644
--- a/lib/authorization.rb
+++ b/lib/authorization.rb
@@ -58,7 +58,7 @@ module OpenTox
# @param [String, String]Username,Password
# @return [String, nil] gives subjectid or nil
def self.authenticate(user, pw)
- return true if !AA_SERVER
+ return nil if !AA_SERVER
begin
resource = RestClient::Resource.new("#{AA_SERVER}/auth/authenticate")
out = resource.post(:username=>user, :password => pw).sub("token.id=","").sub("\n","")
@@ -192,10 +192,9 @@ module OpenTox
# return [Boolean] returns true if policy is created
def self.create_policy(policy, subjectid)
begin
-# resource = RestClient::Resource.new("#{AA_SERVER}/Pol/opensso-pol")
+ resource = RestClient::Resource.new("#{AA_SERVER}/Pol/opensso-pol")
LOGGER.debug "OpenTox::Authorization.create_policy policy: #{policy[168,43]} with token:" + subjectid.to_s + " length: " + subjectid.length.to_s
-# return true if resource.post(policy, :subjectid => subjectid, :content_type => "application/xml")
- return true if RestClientWrapper.post("#{AA_SERVER}/pol", policy, {:subjectid => subjectid, :content_type => "application/xml"})
+ return true if resource.post(policy, :subjectid => subjectid, :content_type => "application/xml")
rescue
return false
end
@@ -306,7 +305,6 @@ module OpenTox
# if no policy exists, create a policy, return result of send policy
send_policy(uri, subjectid)
else
- LOGGER.debug "OpenTox::Authorization.check_policy URI: #{uri} has already a Policy."
# if policy exists check for POST rights
if authorize(uri, "POST", subjectid)
true
@@ -328,62 +326,56 @@ module OpenTox
# @param [String] subjectid
# @return [Boolean] true if access granted, else otherwise
def self.authorized?(uri, request_method, subjectid)
- if OpenTox::Authorization.whitelisted?(uri, request_method)
- LOGGER.debug "authorized? >>true<< (uris is whitelisted), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
- true
- elsif CONFIG[:authorization][:authorize_request].include?(request_method)
- ret = OpenTox::Authorization.authorize(uri, request_method, subjectid)
- LOGGER.debug "authorized? >>#{ret}<< (uri authorized), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
- ret
+ if CONFIG[:authorization][:free_request].include?(request_method)
+ #LOGGER.debug "authorized? >>true<< (request is free), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
+ true
+ elsif OpenTox::Authorization.free_uri?(uri, request_method)
+ #LOGGER.debug "authorized? >>true<< (uris is free_uri), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
+ true
elsif CONFIG[:authorization][:authenticate_request].include?(request_method)
ret = OpenTox::Authorization.is_token_valid(subjectid)
- LOGGER.debug "authorized? >>#{ret}<< (token is valid), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
+ #LOGGER.debug "authorized? >>#{ret}<< (token is in/valid), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
+ ret
+ elsif OpenTox::Authorization.authorize_exception?(uri, request_method)
+ ret = OpenTox::Authorization.is_token_valid(subjectid)
+ #LOGGER.debug "authorized? >>#{ret}<< (uris is authorize exception, token is in/valid), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
+ ret
+ elsif CONFIG[:authorization][:authorize_request].include?(request_method)
+ ret = OpenTox::Authorization.authorize(uri, request_method, subjectid)
+ LOGGER.debug "authorized? >>#{ret}<< (uri (not) authorized), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
ret
else
- LOGGER.debug "authorized? >>true<< (request is free), method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
- true
+ LOGGER.error "invalid request/uri method: #{request_method}, URI: #{uri}, subjectid: #{subjectid}"
+ false
end
end
- @@whitelist = {}
-
private
- def self.whitelisted?(uri, request_method)
- return false unless @@whitelist[request_method]
- @@whitelist[request_method].each do |regexp,invert|
- if invert
- return true if !regexp.match(uri)
- else
- return true if regexp.match(uri)
+ def self.free_uri?(uri, request_method)
+ if CONFIG[:authorization][:free_uris]
+ CONFIG[:authorization][:free_uris].each do |request_methods,uris|
+ if request_methods and uris and request_methods.include?(request_method.to_sym)
+ uris.each do |u|
+ return true if u.match uri
+ end
+ end
end
- end
+ end
return false
end
- public
- # adds uri/regexp-for-matching-uri to the whitelist for a request-method (i.e. access will be granted without cheking the A&A service)
- # @param [String or Regexp] uri_match if string match must be ecaxt
- # @param [String] request_method, must be GET, POST, PUT, DELETE
- # @param [Boolean,optional] invert, set to true if you want to whitelist everything that does not match (careful!)
- def self.whitelist(uri_match, request_method, invert=false)
- if uri_match.is_a?(Regexp)
- uri_regex = uri_match
- elsif uri_match.is_a?(String)
- uri_regex = Regexp.new("^"+uri_match+"$")
- else
- raise "uri-match param is neither string(->exact uri match) nor regexp: "+uri_match.class.to_s
- end
- LOGGER.info("whitelisted "+request_method.to_s+" "+uri_regex.to_s)
- @@whitelist[request_method] = [] unless @@whitelist[request_method]
- @@whitelist[request_method] << [ uri_regex, invert ]
- end
+ def self.authorize_exception?(uri, request_method)
+ if CONFIG[:authorization][:authorize_exceptions]
+ CONFIG[:authorization][:authorize_exceptions].each do |request_methods,uris|
+ if request_methods and uris and request_methods.include?(request_method.to_sym)
+ uris.each do |u|
+ return true if u.match uri
+ end
+ end
+ end
+ end
+ return false
+ end
end
-end
-
-# PENDING delete as soon as new free uri handling is merged
-# this allows GET access to all URIS that do NOT end with /<number> or /<number>/
-OpenTox::Authorization.whitelist( /\/[0-9]+(\/?)$/, "GET", true )
-OpenTox::Authorization.whitelist( /\/[0-9]+(\/?)$/, "POST", true )
-
-
+end \ No newline at end of file
diff --git a/lib/helper.rb b/lib/helper.rb
index afeeb43..5a2436f 100644
--- a/lib/helper.rb
+++ b/lib/helper.rb
@@ -9,6 +9,7 @@ helpers do
end
elsif !env["session"] && subjectid
unless authorized?(subjectid)
+ LOGGER.debug "URI not authorized: clean: " + clean_uri("#{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']}").to_s + " full: #{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']} with request: #{request.env['REQUEST_METHOD']}"
raise OpenTox::NotAuthorizedError.new "Not authorized"
end
else
@@ -27,29 +28,23 @@ helpers do
#cleans URI from querystring and file-extension. Sets port 80 to emptystring
# @param [String] uri
def clean_uri(uri)
+ uri = uri.sub(" ", "%20") #dirty hacks => to fix
+ uri = uri[0,uri.index("InChI=")] if uri.index("InChI=")
+
out = URI.parse(uri)
- out.path = out.path[0, out.path.rindex(/[0-9]/) + 1] if out.path.rindex(/[0-9]/) #cuts after id for a&a
- "#{out.scheme}:" + (out.port != 80 ? out.port : "") + "//#{out.host}#{out.path}"
+ out.path = out.path[0, out.path.length - (out.path.reverse.rindex(/\/{1}\d+\/{1}/))] if out.path.index(/\/{1}\d+\/{1}/) #cuts after /id/ for a&a
+ "#{out.scheme}:" + (out.port != 80 ? out.port : "") + "//#{out.host}#{out.path.chomp('/')}"
end
- #unprotected uris for login/logout, webapplication ...
- def unprotected_requests
- case env['REQUEST_URI']
- when /\/login$|\/logout$|\/predict$|\/toxcreate\/models$/
- return true
- when /\/features/
- return false
- when /\/compound|\/feature|\/task|\/toxcreate/ #to fix: read from config | validation should be protected
- return true
- else
- return false
- end
+ #unprotected uri for login
+ def login_requests
+ return env['REQUEST_URI'] =~ /\/login$/
end
end
before do
- unless !AA_SERVER or unprotected_requests or CONFIG[:authorization][:free_request].include?(env['REQUEST_METHOD'])
+ unless !AA_SERVER or login_requests or CONFIG[:authorization][:free_request].include?(env['REQUEST_METHOD'])
begin
subjectid = nil
subjectid = session[:subjectid] if session[:subjectid]
@@ -59,7 +54,7 @@ before do
subjectid = CGI.unescape(subjectid) if subjectid.include?("%23")
@subjectid = subjectid
rescue
- LOGGER.debug "OpenTox ruby api wrapper: helper before filter: NO subjectid for URI: #{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']}"
+ #LOGGER.debug "OpenTox ruby api wrapper: helper before filter: NO subjectid for URI: #{request.env['rack.url_scheme']}://#{request.env['HTTP_HOST']}#{request.env['REQUEST_URI']}"
subjectid = ""
end
@subjectid = subjectid
diff --git a/lib/rest_client_wrapper.rb b/lib/rest_client_wrapper.rb
index 626f94f..7a6ed2a 100644
--- a/lib/rest_client_wrapper.rb
+++ b/lib/rest_client_wrapper.rb
@@ -64,6 +64,9 @@ module OpenTox
## PENDING partner services accept subjectid only in header
headers[:subjectid] = payload.delete(:subjectid) if payload and payload.is_a?(Hash) and payload.has_key?(:subjectid)
+ # PENDING needed for NUTA, until we finally agree on how to send subjectid
+ headers[:subjectid] = payload.delete(:subjectid) if uri=~/ntua/ and payload and payload.is_a?(Hash) and payload.has_key?(:subjectid)
+
begin
#LOGGER.debug "RestCall: "+rest_call.to_s+" "+uri.to_s+" "+headers.inspect+" "+payload.inspect
resource = RestClient::Resource.new(uri,{:timeout => 60})
diff --git a/lib/task.rb b/lib/task.rb
index 27dc1c2..0ee3a11 100644
--- a/lib/task.rb
+++ b/lib/task.rb
@@ -84,6 +84,16 @@ module OpenTox
task
end
+ # Find a task for querying, status changes
+ # @param [String] uri Task URI
+ # @return [OpenTox::Task] Task object
+ def self.exist?(uri)
+ begin
+ return find(uri)
+ rescue
+ end
+ end
+
# Get a list of all tasks
# @param [optional, String] uri URI of task service
# @return [text/uri-list] Task URIs
diff --git a/lib/templates/config.yaml b/lib/templates/config.yaml
index 116f462..8a5e460 100644
--- a/lib/templates/config.yaml
+++ b/lib/templates/config.yaml
@@ -39,16 +39,48 @@
# Uncomment for verbose logging
# :logger: debug
-
+# :backtrace: 1
+
+
# OpenSSO Authorization
# set ":server: " to disable A&A
:authorization:
:server: "https://opensso.in-silico.ch"
- :free_request: #not controlled by A&A
- - "GET"
+ :free_request: #request-method not controlled by A&A
+ - "GET"
:authenticate_request: #only for authenticated user
- "POST"
:authorize_request: #only for authenticated and authorizeduser
- "DELETE"
- "PUT"
+ # Exceptions:
+ :free_uris: #request-method for uri not controlled by A&A
+ ? - :GET
+ : - !ruby/regexp /localhost\/algorithm/
+ - "http://localhost/dataset"
+ - "http://localhost/model"
+ - "http://localhost/validation"
+ - "http://localhost/validation/crossvalidation"
+ - "http://localhost/validation/reach_report"
+ - "http://localhost/validation/reach_report/crossvalidation"
+ - "http://localhost/validation/report"
+ - "http://localhost/validation/report/crossvalidation"
+ - "http://localhost/validation/reach_report/qmrf"
+ ? - :GET
+ - :POST
+ : - !ruby/regexp /localhost\/toxcreate/
+ - !ruby/regexp /localhost\/task/
+ - !ruby/regexp /localhost\/compound/
+ ? - :PUT
+ : - !ruby/regexp /localhost\/task/
+
+ :authorize_exceptions: #request-method for uri only authenticated, no authorization
+ ? - :POST
+ : - !ruby/regexp /localhost\/algorithm/
+ - "http://localhost/dataset"
+ - "http://localhost/model"
+ - "http://localhost/validation"
+ - !ruby/regexp /localhost\/validation\/[a-z,A-Z,\/,_\-]*$/
+
+
\ No newline at end of file
diff --git a/lib/validation.rb b/lib/validation.rb
index f0c5297..a47a554 100644
--- a/lib/validation.rb
+++ b/lib/validation.rb
@@ -88,11 +88,11 @@ module OpenTox
# looks for report for this crossvalidation, creates a report if no report is found
# @param [String,optional] subjectid
# @param [OpenTox::Task,optional] waiting_task (can be a OpenTox::Subtask as well), progress is updated accordingly
- # @return [OpenTox::CrossvalidationReport]
+ # @return [String] report uri
def find_or_create_report( subjectid=nil, waiting_task=nil )
@report = CrossvalidationReport.find_for_crossvalidation(@uri, subjectid) unless @report
@report = CrossvalidationReport.create(@uri, subjectid, waiting_task) unless @report
- @report
+ @report.uri
end
# loads metadata via yaml from crossvalidation object