Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# Changelog

## 4.2.0
* Support Rails 8.1
* Drop support for Rails < 7.1
* Remove deprecated `attr_accessible` from MySQL2 adapter
* Replace deprecated `sanitize_sql_for_conditions` with `sanitize_sql`
* Fix `postgres?` detection to use `connection_db_config` instead of deprecated `ActiveRecord::Base.connection.class.name`
* Fix `serialize` to use keyword argument `coder:` as required by Rails 8.0+
* Fix `connection.execute` result handling in MySQL2 adapter for `ActiveRecord::Result` compatibility
* Remove legacy ActiveRecord < 6.1 code paths from `db_config` and `connection_db_config`
* Remove deprecated `test_files` from gemspec
* Widen `activerecord-import` dependency to `>= 1.0`

## 4.1.3
* Updated `accessible_objects_for_operations_function` for better filter performance

Expand Down
19 changes: 19 additions & 0 deletions factbook.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: backstage.io/v1alpha1
kind: Component
spec:
type: library
lifecycle: production
owner: ejinotti@mdsol.com
experience: enablement
metadata:
json_schema: https://github.com/mdsol/platform-standards/tree/main/schemas/v1alpha1.schema.json
name: the_policy_machine
title: The Policy Machine
description: A ruby implementation of the Policy Machine authorization formalism.
teams:
- number: 16
people:
- role: technical owner
email: ejinotti@mdsol.com
annotations:
product: Platform Services - Authorization Service
2 changes: 1 addition & 1 deletion lib/policy_machine/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
class PolicyMachine
VERSION = "4.1.3"
VERSION = "4.2.0"
Comment thread
afeng-mdsol marked this conversation as resolved.
end
39 changes: 5 additions & 34 deletions lib/policy_machine_storage_adapters/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,41 +40,12 @@ def self.load_db_adapter!
def self.db_config
return @_db_config if @_db_config

ar_configs = PolicyElement.configurations

# ActiveRecord < 6.0
unless ar_configs.respond_to?(:configs_for)
@_db_config = ar_configs[Rails.env].symbolize_keys
return @_db_config
end

config = begin
# ActiveRecord >= 6.1:
# there is a deprecation warning for using kwarg 'spec_name'
# so try the new 'name' kwarg first
ar_configs.configs_for(env_name: Rails.env, name: 'primary')
rescue ArgumentError
# ActiveRecord == 6.0:
# the kwarg is called 'spec_name'
ar_configs.configs_for(env_name: Rails.env, spec_name: 'primary')
end

@_db_config =
# AR 6.1 also emits a warning that `.config` is deprecated
# and `.configuration_hash` is The New Way
if config.respond_to?(:configuration_hash)
config.configuration_hash
else
config.config.symbolize_keys
end
config = PolicyElement.configurations.configs_for(env_name: Rails.env, name: 'primary')
@_db_config = config.configuration_hash
end

def self.connection_db_config
if ::ActiveRecord::Base.respond_to?(:connection_db_config)
::ActiveRecord::Base.connection_db_config.configuration_hash
else
Comment on lines -73 to -75

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious, why did this need to be changed?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ActiveRecord::Base.connection_config was deprecated sometime after Rails 6.1.
rails/rails#38005

::ActiveRecord::Base.connection_config
end
::ActiveRecord::Base.connection_db_config.configuration_hash
end

def self.buffering?
Expand Down Expand Up @@ -286,7 +257,7 @@ def pluck_ancestor_tree(filters: {}, fields:)

def self.serialize(store:, name:, serializer: nil)
# Use the passed serializer if present, otherwise use Rails' default serialization
active_record_serialize store, serializer if serializer
active_record_serialize store, coder: serializer if serializer

store_accessor store, name
end
Expand Down Expand Up @@ -1363,6 +1334,6 @@ def transaction_without_mergejoin(&block)
end

def self.postgres?
::ActiveRecord::Base.connection.class.name == 'ActiveRecord::ConnectionAdapters::PostgreSQLAdapter'
::ActiveRecord::Base.connection_db_config.adapter == 'postgresql'
end
end unless active_record_unavailable
5 changes: 2 additions & 3 deletions lib/policy_machine_storage_adapters/active_record/mysql2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class TransitiveClosure < ::ActiveRecord::Base

after_create :add_to_transitive_closure
after_destroy :remove_from_transitive_closure
attr_accessible :child_id, :parent_id
# needs parent_id, child_id columns
belongs_to :parent, class_name: :PolicyElement
belongs_to :child, class_name: :PolicyElement
Expand Down Expand Up @@ -46,8 +45,8 @@ def add_to_transitive_closure
def remove_from_transitive_closure
parents_ancestors = connection.execute("Select ancestor_id from transitive_closure where descendant_id=#{parent_id}")
childs_descendants = connection.execute("Select descendant_id from transitive_closure where ancestor_id=#{child_id}")
parents_ancestors = parents_ancestors.to_a.<<(parent_id).join(',')
childs_descendants = childs_descendants.to_a.<<(child_id).join(',')
parents_ancestors = parents_ancestors.rows.flatten.<<(parent_id).join(',')
childs_descendants = childs_descendants.rows.flatten.<<(child_id).join(',')

connection.execute("Delete from transitive_closure where
ancestor_id in (#{parents_ancestors}) and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ def self.find_ancestor_ids(root_element_ids)
(
SELECT parent_id, child_id
FROM assignments
WHERE #{sanitize_sql_for_conditions(["child_id IN (:root_ids)", root_ids: root_element_ids])}
WHERE #{sanitize_sql(["child_id IN (:root_ids)", root_ids: root_element_ids])}
)
UNION ALL
(
Expand Down Expand Up @@ -456,7 +456,7 @@ def self.filter_operation_set_list_by_assigned_operation(operation_set_ids, oper
(
SELECT parent_id, child_id, ARRAY[parent_id] AS parents
FROM assignments
WHERE #{sanitize_sql_for_conditions(["parent_id IN (:opset_ids)", opset_ids: operation_set_ids])}
WHERE #{sanitize_sql(["parent_id IN (:opset_ids)", opset_ids: operation_set_ids])}
)
UNION ALL
(
Expand All @@ -471,7 +471,7 @@ def self.filter_operation_set_list_by_assigned_operation(operation_set_ids, oper
FROM assignments_recursive
JOIN policy_elements
ON policy_elements.id = assignments_recursive.child_id
WHERE #{sanitize_sql_for_conditions(["policy_elements.unique_identifier=:op_id", op_id: operation_id])}
WHERE #{sanitize_sql(["policy_elements.unique_identifier=:op_id", op_id: operation_id])}
AND type = 'PolicyMachineStorageAdapter::ActiveRecord::Operation'
SQL

Expand Down
4 changes: 2 additions & 2 deletions policy_machine.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]

s.add_dependency('activesupport')
s.add_dependency('activerecord', '~> 7.1') #TODO optional dependency when not using active record adapter
s.add_dependency('activerecord', '~> 8.1') #TODO optional dependency when not using active record adapter
Comment thread
afeng-mdsol marked this conversation as resolved.
Outdated
s.add_dependency('bootsnap')
s.add_dependency('kaminari')
s.add_dependency('listen')
Expand All @@ -33,5 +33,5 @@ Gem::Specification.new do |s|
s.add_development_dependency('byebug')
s.add_development_dependency('neography', '~> 1.1')
s.add_development_dependency('database_cleaner', '~> 2')
s.add_development_dependency('rails', '~> 7.1')
s.add_development_dependency('rails', '~> 8.1')
end
4 changes: 3 additions & 1 deletion spec/policy_machine_storage_adapters/active_record_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2285,7 +2285,9 @@
obj = policy_machine.send("create_#{type}", SecureRandom.uuid)

sql = "SELECT extra_attributes FROM policy_elements WHERE id = #{obj.id}"
result = ActiveRecord::Base.connection.execute(sql)
result = ActiveRecord::Base.with_connection do |connection|
connection.execute(sql)
end
database_entry = result[0]["extra_attributes"]

expect(database_entry).to eq('{}')
Expand Down
2 changes: 1 addition & 1 deletion test/tasks/setup.rake
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace :pm do
`bundle exec rails generate the_policy_machine:update_policy_element_associations_table -f`
`bundle exec rails generate the_policy_machine:accessible_objects_for_operations_function -f`
`bundle exec rails generate the_policy_machine:update_accessible_objects_filter_performance -f`
FileUtils.cp('../add_test_columns_migration.rb', './db/migrate/99999999999999_add_test_columns.rb')
FileUtils.cp('../add_test_columns_migration.rb', './db/migrate/20260624162522_add_test_columns.rb')

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ActiveRecord::InvalidMigrationTimestampError:  (ActiveRecord::InvalidMigrationTimestampError)

Invalid timestamp 99999999999999 for migration file: add_test_columns.
Timestamp must be in form YYYYMMDDHHMMSS, and less than 20260624162521.

when setting up the test db to run specs


`bundle exec rake db:create db:migrate`
`RAILS_ENV=test bundle exec rake db:migrate`
Expand Down