-
Notifications
You must be signed in to change notification settings - Fork 74
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move connector extensions out of app/
- Loading branch information
1 parent
b8c8143
commit b17c619
Showing
3 changed files
with
144 additions
and
139 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,23 @@ | ||
# frozen_string_literal: true | ||
|
||
Rails.application.config.to_prepare do | ||
ActiveSupport.on_load(:active_record) do | ||
if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) | ||
ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do | ||
include ApiAuthentication::ByAccessToken::ConnectionExtension | ||
end | ||
ActiveSupport.on_load(:active_record) do | ||
require "api_authentication.rb" | ||
|
||
if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter) | ||
ActiveRecord::ConnectionAdapters::Mysql2Adapter.class_eval do | ||
include ApiAuthentication::ConnectorExtensions::ConnectionExtension | ||
end | ||
end | ||
|
||
if defined?(ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter) | ||
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do | ||
include ApiAuthentication::ByAccessToken::OracleEnhancedConnectionExtension | ||
end | ||
if defined?(ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter) | ||
ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.class_eval do | ||
include ApiAuthentication::ConnectorExtensions::OracleEnhancedConnectionExtension | ||
end | ||
end | ||
|
||
if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) | ||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do | ||
include ApiAuthentication::ByAccessToken::ConnectionExtension | ||
end | ||
if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) | ||
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do | ||
include ApiAuthentication::ConnectorExtensions::ConnectionExtension | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
# frozen_string_literal: true | ||
|
||
module ApiAuthentication | ||
|
||
Error = Class.new(StandardError) | ||
|
||
ScopeError = Class.new(Error) | ||
PermissionError = Class.new(Error) | ||
|
||
module PermissionEnforcer | ||
|
||
extend self | ||
|
||
READ_ONLY = 'ro' | ||
READ_WRITE = 'rw' | ||
|
||
def set_transaction | ||
case level | ||
when READ_ONLY then 'SET TRANSACTION READ ONLY' | ||
when READ_WRITE then 'SET TRANSACTION READ WRITE' | ||
end | ||
end | ||
|
||
def start_transaction | ||
case level | ||
when READ_ONLY then 'START TRANSACTION READ ONLY' | ||
when READ_WRITE then 'START TRANSACTION READ WRITE' | ||
end | ||
end | ||
|
||
class EnforceError < StandardError | ||
end | ||
|
||
def enforce(access_token, &block) | ||
self.level = access_token&.permission | ||
|
||
return yield unless requires_transaction? | ||
|
||
if connection.transaction_open? | ||
raise "Can't use read-only Access Token with transactional fixtures" if Rails.env.test? | ||
|
||
error = EnforceError.new("couldn't open new transaction to enforce read-only access token") | ||
System::ErrorReporting.report_error(error) | ||
end | ||
|
||
connection.transaction(requires_new: true, &block) | ||
rescue ActiveRecord::StatementInvalid => error | ||
if error.message =~ /read(-|\s)only transaction/i | ||
raise PermissionError, error.message, caller | ||
else | ||
raise | ||
end | ||
ensure | ||
Rails.logger.info "PermissionEnforcer#ensure clear level" | ||
self.level = nil | ||
end | ||
|
||
def read_only? | ||
level == READ_ONLY | ||
end | ||
|
||
private | ||
|
||
def requires_transaction? | ||
case level | ||
when READ_ONLY then true | ||
when READ_WRITE then false | ||
end | ||
end | ||
|
||
THREAD_VARIABLE = :__permission_enforcer_level | ||
|
||
def level=(level) | ||
Rails.logger.info "PermissionEnforcer: level = #{level}" | ||
Thread.current[THREAD_VARIABLE] = level | ||
end | ||
|
||
def level | ||
Thread.current[THREAD_VARIABLE] | ||
end | ||
|
||
def connection | ||
ActiveRecord::Base.connection | ||
end | ||
end | ||
|
||
module ConnectorExtensions | ||
module ReadOnlyTransaction | ||
def read_only_transaction? | ||
::ApiAuthentication::PermissionEnforcer.read_only? | ||
end | ||
end | ||
|
||
module ConnectionExtension | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
prepend TransactionMethods | ||
end | ||
|
||
module TransactionMethods | ||
include ReadOnlyTransaction | ||
|
||
def begin_db_transaction | ||
transaction = ::ApiAuthentication::PermissionEnforcer.start_transaction | ||
transaction ? execute(transaction) : super | ||
end | ||
end | ||
end | ||
|
||
module OracleEnhancedConnectionExtension | ||
extend ActiveSupport::Concern | ||
|
||
included do | ||
prepend TransactionMethods | ||
end | ||
|
||
module TransactionMethods | ||
include ReadOnlyTransaction | ||
|
||
def begin_db_transaction | ||
super | ||
|
||
transaction = ::ApiAuthentication::PermissionEnforcer.set_transaction | ||
execute(transaction) if transaction | ||
end | ||
end | ||
end | ||
end | ||
end |