Skip to content

Commit

Permalink
Merge remote-tracking branch 'ecoportal/ecoportal-ontoportal-reset' i…
Browse files Browse the repository at this point in the history
…nto ecoportal-ontoportal-reset
  • Loading branch information
syphax-bouazzouni committed Sep 12, 2023
2 parents 9649e57 + fa6bf5d commit 24700f1
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 27 deletions.
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ gem 'rest-client'
gem 'rsolr', '~> 1.0'
gem 'rubyzip', '~> 1.0'
gem 'thin'
gem "oauth2", "~> 2.0"
gem 'request_store'

# Testing
group :test do
gem 'email_spec'
Expand Down
34 changes: 25 additions & 9 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@ GEM
multi_json (~> 1.3)
thread_safe (~> 0.1)
tzinfo (~> 0.3.37)
addressable (2.8.4)
addressable (2.8.5)
public_suffix (>= 2.0.2, < 6.0)
ansi (1.5.0)
ast (2.4.2)
base64 (0.1.1)
bcrypt (3.1.19)
builder (3.2.4)
coderay (1.1.3)
Expand Down Expand Up @@ -85,6 +86,7 @@ GEM
concurrent-ruby (~> 1.0)
json (2.6.3)
json_pure (2.6.3)
jwt (2.7.1)
language_server-protocol (3.17.0.3)
launchy (2.5.2)
addressable (~> 2.8)
Expand All @@ -98,20 +100,21 @@ GEM
net-pop
net-smtp
method_source (1.0.0)
mime-types (3.4.1)
mime-types (3.5.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2023.0218.1)
mini_mime (1.1.2)
mime-types-data (3.2023.0808)
mini_mime (1.1.5)
minitest (4.7.5)
minitest-reporters (0.14.24)
ansi
builder
minitest (>= 2.12, < 5.0)
powerbar
multi_json (1.15.0)
multi_xml (0.6.0)
multipart-post (2.3.0)
net-http-persistent (2.9.4)
net-imap (0.3.6)
net-imap (0.3.7)
date
net-protocol
net-pop (0.1.2)
Expand All @@ -121,6 +124,13 @@ GEM
net-smtp (0.3.3)
net-protocol
netrc (0.11.0)
oauth2 (2.0.9)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
multi_xml (~> 0.5)
rack (>= 1.2, < 4)
snaky_hash (~> 2.0)
version_gem (~> 1.1)
oj (2.18.5)
omni_logger (0.1.4)
logger
Expand All @@ -144,9 +154,9 @@ GEM
rake (10.5.0)
rdf (1.0.8)
addressable (>= 2.2)
redis (5.0.6)
redis (5.0.7)
redis-client (>= 0.9.0)
redis-client (0.14.1)
redis-client (0.17.0)
connection_pool
regexp_parser (2.8.1)
request_store (1.5.1)
Expand All @@ -156,10 +166,11 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
rexml (3.2.5)
rexml (3.2.6)
rsolr (1.1.2)
builder (>= 2.1.2)
rubocop (1.55.0)
rubocop (1.56.3)
base64 (~> 0.1.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
parallel (~> 1.10)
Expand All @@ -184,6 +195,9 @@ GEM
simplecov (~> 0.19)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
snaky_hash (2.0.1)
hashie
version_gem (~> 1.1, >= 1.1.1)
systemu (2.6.5)
test-unit-minitest (0.9.1)
minitest (~> 4.7)
Expand All @@ -200,6 +214,7 @@ GEM
unicode-display_width (2.4.2)
uuid (2.3.9)
macaddr (~> 1.0)
version_gem (1.1.3)

PLATFORMS
x86_64-darwin-21
Expand All @@ -218,6 +233,7 @@ DEPENDENCIES
minitest
minitest-reporters (>= 0.5.0)
multi_json (~> 1.0)
oauth2 (~> 2.0)
oj (~> 2.0)
omni_logger
pony
Expand Down
6 changes: 3 additions & 3 deletions lib/ontologies_linked_data/models/identifier_request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ class IdentifierRequest < LinkedData::Models::Base
LinkedData::Hypermedia::Link.new("submission", lambda {|r| "identifier_requests/#{r.requestId}/submission"}, LinkedData::Models::OntologySubmission.uri_type)

# Access control
read_restriction_based_on lambda {|req| req.submission.ontology}
access_control_load submission: [ontology: [:administeredBy, :acl, :viewingRestriction]]
write_access submission: [ontology: [:administeredBy]]
#read_restriction_based_on lambda {|req| req.submission.ontology}
#access_control_load submission: [ontology: [:administeredBy, :acl, :viewingRestriction]]
#write_access submission: [ontology: [:administeredBy]]
#access_control_load submission: [:access_control_load_attrs]

embed :submission, :requestedBy, :processedBy
Expand Down
4 changes: 2 additions & 2 deletions lib/ontologies_linked_data/models/ontology_submission.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,8 @@ def self.embed_values_hash

# Links
links_load :submissionId, ontology: [:acronym]
link_to LinkedData::Hypermedia::Link.new("metrics", ->(s) { "#{self.ontology_link(s)}/submissions/#{s.submissionId}/metrics" }, self.type_uri)
LinkedData::Hypermedia::Link.new("download", ->(s) { "#{self.ontology_link(s)}/submissions/#{s.submissionId}/download" }, self.type_uri)
link_to LinkedData::Hypermedia::Link.new("metrics", ->(s) { "#{self.ontology_link(s)}/submissions/#{s.id.split('/').last}/metrics" }, self.type_uri)
LinkedData::Hypermedia::Link.new("download", ->(s) { "#{self.ontology_link(s)}/submissions/#{s.id.split('/').last}/download" }, self.type_uri)

# HTTP Cache settings
cache_timeout 3600
Expand Down
72 changes: 59 additions & 13 deletions lib/ontologies_linked_data/security/authorization.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
require 'set'
require 'jwt'

module LinkedData
module Security
class Authorization
def self.decodeJWT(encodedToken)
rsa_public = OpenSSL::X509::Certificate.new(
Base64.decode64(LinkedData.settings.oauth2_authorization_server_signature_cert)).public_key
decoded_token = JWT.decode encodedToken, rsa_public, true, { algorithm: LinkedData.settings.oauth2_authorization_server_signature_alg,
verify_iat: true,
verify_not_before: true,
verify_expiration: true,
verify_aud: true,
aud: LinkedData.settings.oauth2_audience,
verify_iss: true,
iss: LinkedData.settings.oauth_issuer }
decoded_token
end

APIKEYS_FOR_AUTHORIZATION = {}

def initialize(app = nil)
Expand All @@ -19,23 +34,44 @@ def initialize(app = nil)
def call(env)
req = Rack::Request.new(env)
params = req.params
apikey = find_apikey(env, params)
access_token = nil
apikey = nil

unless apikey
status = 401
response = {
status: status,
error: "You must provide an API Key either using the query-string parameter `apikey` or the `Authorization` header: `Authorization: apikey token=my_apikey`. " + \
"Your API Key can be obtained by logging in at #{LinkedData.settings.ui_host}/account"
}
end
access_token = find_access_token(env, params) if LinkedData.settings.oauth2_enabled
apikey = find_apikey(env, params) unless access_token

if status != 401 && !authorized?(apikey, env)
if apikey
unless authorized?(apikey, env)
status = 401
response = {
status: status,
error: "You must provide a valid API Key. " + \
"Your API Key can be obtained by logging in at #{LinkedData.settings.ui_host}/account"
}
end
elsif access_token
begin
Authorization::decodeJWT(access_token)
rescue JWT::DecodeError => e
LOGGER.debug(e.message)
status = 401
response = {
status: status,
error: "Failed to decode JWT token: " + e.message
}
end
else
status = 401
error_message = "You must provide an API Key either using the query-string parameter `apikey` or the `Authorization` header: `Authorization: apikey token=my_apikey`. " + \
"Your API Key can be obtained by logging in at #{LinkedData.settings.ui_host}/account"

if LinkedData.settings.oauth2_enabled
error_message = error_message + "Alternatively, you must supply an OAuth2 access token in the `Authorization` header: `Authorization: Bearer oauth2-access-token`."
end

response = {
status: status,
error: "You must provide a valid API Key. " + \
"Your API Key can be obtained by logging in at #{LinkedData.settings.ui_host}/account"
error: error_message
}
end

Expand Down Expand Up @@ -76,7 +112,7 @@ def find_apikey(env, params)
apikey = params["userapikey"]
elsif params["apikey"]
apikey = params["apikey"]
elsif apikey.nil? && header_auth
elsif apikey.nil? && header_auth && !header_auth.empty?
token = Rack::Utils.parse_query(header_auth.split(" ")[1])
# Strip spaces from start and end of string
apikey = token["token"].gsub(/\"/, "")
Expand All @@ -93,6 +129,16 @@ def find_apikey(env, params)
apikey
end

def find_access_token(env, params)
access_token = nil
header_auth = env["HTTP_AUTHORIZATION"] || env["Authorization"]
if header_auth && header_auth.downcase().start_with?("bearer ")
access_token = header_auth.split()[1]
end
access_token
end


def authorized?(apikey, env)
return false if apikey.nil?
if APIKEYS_FOR_AUTHORIZATION.key?(apikey)
Expand Down

0 comments on commit 24700f1

Please sign in to comment.