|
1 | 1 | # frozen_string_literal: true |
2 | 2 |
|
3 | 3 | require "active_record/connection_adapters/oracle_enhanced/database_tasks" |
| 4 | +require "active_support/testing/stream" |
4 | 5 | require "stringio" |
5 | 6 | require "tempfile" |
6 | 7 |
|
@@ -65,6 +66,75 @@ def fake_terminal(input) |
65 | 66 | end |
66 | 67 | end |
67 | 68 |
|
| 69 | + describe "create input validation" do |
| 70 | + around do |example| |
| 71 | + original_stderr, $stderr = $stderr, StringIO.new |
| 72 | + example.run |
| 73 | + ensure |
| 74 | + $stderr = original_stderr |
| 75 | + end |
| 76 | + |
| 77 | + it "raises ArgumentError before touching the database when :username is not an Oracle identifier" do |
| 78 | + invalid_config = config.merge(username: "oracle;DROP USER system;--") |
| 79 | + expect(ActiveRecord::Base).not_to receive(:establish_connection) |
| 80 | + expect { |
| 81 | + ActiveRecord::Tasks::DatabaseTasks.create(invalid_config) |
| 82 | + }.to raise_error(ArgumentError, /Invalid Oracle identifier for :username/) |
| 83 | + end |
| 84 | + |
| 85 | + it "raises ArgumentError before touching the database when OracleEnhancedAdapter.permissions contains a statement separator" do |
| 86 | + original_permissions = ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.permissions |
| 87 | + ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.permissions = |
| 88 | + ["create session; DROP USER system;--"] |
| 89 | + expect(ActiveRecord::Base).not_to receive(:establish_connection) |
| 90 | + expect { |
| 91 | + ActiveRecord::Tasks::DatabaseTasks.create(config.merge(username: "oracle_enhanced_test_user")) |
| 92 | + }.to raise_error(ArgumentError, /Invalid Oracle privilege in OracleEnhancedAdapter.permissions/) |
| 93 | + ensure |
| 94 | + ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.permissions = original_permissions |
| 95 | + end |
| 96 | + |
| 97 | + it "raises ArgumentError before touching the database when OracleEnhancedAdapter.permissions contains a newline" do |
| 98 | + original_permissions = ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.permissions |
| 99 | + ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.permissions = ["create\nsession"] |
| 100 | + expect(ActiveRecord::Base).not_to receive(:establish_connection) |
| 101 | + expect { |
| 102 | + ActiveRecord::Tasks::DatabaseTasks.create(config.merge(username: "oracle_enhanced_test_user")) |
| 103 | + }.to raise_error(ArgumentError, /Invalid Oracle privilege in OracleEnhancedAdapter.permissions/) |
| 104 | + ensure |
| 105 | + ActiveRecord::ConnectionAdapters::OracleEnhancedAdapter.permissions = original_permissions |
| 106 | + end |
| 107 | + end |
| 108 | + |
| 109 | + describe "create password quoting" do |
| 110 | + include ActiveSupport::Testing::Stream |
| 111 | + |
| 112 | + let(:captured_sqls) { [] } |
| 113 | + let(:fake_connection) do |
| 114 | + double("connection").tap do |c| |
| 115 | + allow(c).to receive(:execute) { |sql| captured_sqls << sql } |
| 116 | + end |
| 117 | + end |
| 118 | + |
| 119 | + before do |
| 120 | + allow(ActiveRecord::Base).to receive(:establish_connection) |
| 121 | + allow(ActiveRecord::Base).to receive(:lease_connection).and_return(fake_connection) |
| 122 | + ENV["ORACLE_SYSTEM_PASSWORD"] = "dummy" |
| 123 | + end |
| 124 | + |
| 125 | + after { ENV.delete("ORACLE_SYSTEM_PASSWORD") } |
| 126 | + |
| 127 | + it "wraps :password as a double-quoted literal with embedded double quotes doubled" do |
| 128 | + quietly do |
| 129 | + ActiveRecord::Tasks::DatabaseTasks.create( |
| 130 | + config.merge(username: "oracle_enhanced_test_user", password: %{p"w}) |
| 131 | + ) |
| 132 | + end |
| 133 | + create_sql = captured_sqls.first |
| 134 | + expect(create_sql).to eq(%{CREATE USER oracle_enhanced_test_user IDENTIFIED BY "p""w"}) |
| 135 | + end |
| 136 | + end |
| 137 | + |
68 | 138 | context "with test table" do |
69 | 139 | before(:all) do |
70 | 140 | $stdout, @original_stdout = StringIO.new, $stdout |
|
0 commit comments