pg_audit_log 0.3.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc CHANGED
@@ -13,19 +13,11 @@ Compatible with Rails 3.0.x and 3.1.x
13
13
 
14
14
  == INSTALL
15
15
 
16
- === Enable custom variables in your postgresql instance
16
+ === Enable plpgsql langauges in your postgresql instance
17
17
 
18
- To enable auditing you need to set a variable in your postgresql.conf file:
18
+ As a superuser in postgres make sure your database has plpgsql enabled:
19
19
 
20
- For macports: /opt/local/var/db/postgresql84/defaultdb/postgresql.conf
21
- For homebrew: /usr/local/var/postgres/postgresql.conf
22
- For linux: it varies from distro to distro.
23
-
24
- At the bottom of the file add the following:
25
-
26
- custom_variable_classes = 'audit'
27
-
28
- Then restart your PostgreSQL server
20
+ CREATE OR REPLACE PROCEDURAL LANGUAGE plpgsql;
29
21
 
30
22
  === Rails 3
31
23
 
data/lib/pg_audit_log.rb CHANGED
@@ -7,6 +7,7 @@ require "pg_audit_log/version"
7
7
 
8
8
  case ::ActiveRecord::VERSION::MAJOR
9
9
  when 3
10
+ require "pg_audit_log/extensions/shared/postgresql_adapter.rb"
10
11
  if ::ActiveRecord::VERSION::MINOR == 0
11
12
  require "pg_audit_log/extensions/3.0/postgresql_adapter.rb"
12
13
  else
@@ -3,11 +3,9 @@ require "active_record/connection_adapters/postgresql_adapter"
3
3
  # Did not want to reopen the class but sending an include seemingly is not working.
4
4
  class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
5
5
  def execute_with_auditing(sql, name = nil)
6
- current_user = Thread.current[:current_user]
7
- user_unique_name = current_user.try(:unique_name) || "UNKNOWN"
8
-
9
- log_user_id = %[SET audit.user_id = #{current_user.try(:id) || "-1"}]
10
- log_user_unique_name = %[SET audit.user_unique_name = "#{user_unique_name}"]
6
+ user_id, unique_name = user_id_and_name
7
+ log_user_id = PgAuditLog::Function.user_identifier_temporary_function(user_id)
8
+ log_user_unique_name = PgAuditLog::Function.user_unique_name_temporary_function(unique_name)
11
9
 
12
10
  log([log_user_id, log_user_unique_name, sql].join("; "), name) do
13
11
  if @async
@@ -23,62 +21,5 @@ class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
23
21
  end
24
22
 
25
23
  alias_method_chain :execute, :auditing
26
-
27
- def begin_db_transaction
28
- execute_without_auditing "BEGIN"
29
- end
30
-
31
- # Commits a transaction.
32
- def commit_db_transaction
33
- execute_without_auditing "COMMIT"
34
- end
35
-
36
- # Aborts a transaction.
37
- def rollback_db_transaction
38
- execute_without_auditing "ROLLBACK"
39
- end
40
-
41
- def create_savepoint
42
- execute_without_auditing("SAVEPOINT #{current_savepoint_name}")
43
- end
44
-
45
- def rollback_to_savepoint
46
- execute_without_auditing("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
47
- end
48
-
49
- def release_savepoint
50
- execute_without_auditing("RELEASE SAVEPOINT #{current_savepoint_name}")
51
- end
52
-
53
- def drop_table_with_auditing(table_name, options = {})
54
- if PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
55
- PgAuditLog::Triggers.drop_for_table(table_name)
56
- end
57
- drop_table_without_auditing(table_name, options)
58
- end
59
- alias_method_chain :drop_table, :auditing
60
-
61
- def create_table_with_auditing(table_name, options = {}, &block)
62
- create_table_without_auditing(table_name, options, &block)
63
- unless options[:temporary] ||
64
- PgAuditLog::IGNORED_TABLES.include?(table_name) ||
65
- PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
66
- PgAuditLog::Triggers.create_for_table(table_name)
67
- end
68
- end
69
- alias_method_chain :create_table, :auditing
70
-
71
- def rename_table_with_auditing(table_name, new_name)
72
- rename_table_without_auditing(table_name, new_name)
73
- if PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
74
- PgAuditLog::Triggers.drop_for_table(table_name)
75
- end
76
- unless PgAuditLog::IGNORED_TABLES.include?(table_name) ||
77
- PgAuditLog::Triggers.tables_with_triggers.include?(new_name)
78
- PgAuditLog::Triggers.create_for_table(new_name)
79
- end
80
- end
81
- alias_method_chain :rename_table, :auditing
82
-
83
24
  end
84
25
 
@@ -3,11 +3,9 @@ require "active_record/connection_adapters/postgresql_adapter"
3
3
  # Did not want to reopen the class but sending an include seemingly is not working.
4
4
  class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
5
5
  def generate_auditing_sql(sql)
6
- current_user = Thread.current[:current_user]
7
- user_unique_name = current_user.try(:unique_name) || "UNKNOWN"
8
-
9
- log_user_id = %[SET audit.user_id = #{current_user.try(:id) || "-1"}]
10
- log_user_unique_name = %[SET audit.user_unique_name = "#{user_unique_name}"]
6
+ user_id, unique_name = user_id_and_name
7
+ log_user_id = PgAuditLog::Function.user_identifier_temporary_function(user_id)
8
+ log_user_unique_name = PgAuditLog::Function.user_unique_name_temporary_function(unique_name)
11
9
  { :user_id => log_user_id, :unique_name => log_user_unique_name, :sql => sql }
12
10
  end
13
11
 
@@ -32,62 +30,5 @@ class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
32
30
  end
33
31
  end
34
32
  alias_method_chain :execute, :auditing
35
-
36
- def begin_db_transaction
37
- execute_without_auditing "BEGIN"
38
- end
39
-
40
- # Commits a transaction.
41
- def commit_db_transaction
42
- execute_without_auditing "COMMIT"
43
- end
44
-
45
- # Aborts a transaction.
46
- def rollback_db_transaction
47
- execute_without_auditing "ROLLBACK"
48
- end
49
-
50
- def create_savepoint
51
- execute_without_auditing("SAVEPOINT #{current_savepoint_name}")
52
- end
53
-
54
- def rollback_to_savepoint
55
- execute_without_auditing("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
56
- end
57
-
58
- def release_savepoint
59
- execute_without_auditing("RELEASE SAVEPOINT #{current_savepoint_name}")
60
- end
61
-
62
- def drop_table_with_auditing(table_name, options = {})
63
- if PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
64
- PgAuditLog::Triggers.drop_for_table(table_name)
65
- end
66
- drop_table_without_auditing(table_name, options)
67
- end
68
- alias_method_chain :drop_table, :auditing
69
-
70
- def create_table_with_auditing(table_name, options = {}, &block)
71
- create_table_without_auditing(table_name, options, &block)
72
- unless options[:temporary] ||
73
- PgAuditLog::IGNORED_TABLES.include?(table_name) ||
74
- PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
75
- PgAuditLog::Triggers.create_for_table(table_name)
76
- end
77
- end
78
- alias_method_chain :create_table, :auditing
79
-
80
- def rename_table_with_auditing(table_name, new_name)
81
- rename_table_without_auditing(table_name, new_name)
82
- if PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
83
- PgAuditLog::Triggers.drop_for_table(table_name)
84
- end
85
- unless PgAuditLog::IGNORED_TABLES.include?(table_name) ||
86
- PgAuditLog::Triggers.tables_with_triggers.include?(new_name)
87
- PgAuditLog::Triggers.create_for_table(new_name)
88
- end
89
- end
90
- alias_method_chain :rename_table, :auditing
91
-
92
33
  end
93
34
 
@@ -0,0 +1,68 @@
1
+ require "active_record/connection_adapters/postgresql_adapter"
2
+
3
+ # Did not want to reopen the class but sending an include seemingly is not working.
4
+ class ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
5
+ def begin_db_transaction
6
+ execute_without_auditing "BEGIN"
7
+ end
8
+
9
+ def commit_db_transaction
10
+ execute_without_auditing "COMMIT"
11
+ end
12
+
13
+ def rollback_db_transaction
14
+ execute_without_auditing "ROLLBACK"
15
+ end
16
+
17
+ def create_savepoint
18
+ execute_without_auditing("SAVEPOINT #{current_savepoint_name}")
19
+ end
20
+
21
+ def rollback_to_savepoint
22
+ execute_without_auditing("ROLLBACK TO SAVEPOINT #{current_savepoint_name}")
23
+ end
24
+
25
+ def release_savepoint
26
+ execute_without_auditing("RELEASE SAVEPOINT #{current_savepoint_name}")
27
+ end
28
+
29
+ def drop_table_with_auditing(table_name, options = {})
30
+ if PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
31
+ PgAuditLog::Triggers.drop_for_table(table_name)
32
+ end
33
+ drop_table_without_auditing(table_name, options)
34
+ end
35
+ alias_method_chain :drop_table, :auditing
36
+
37
+ def create_table_with_auditing(table_name, options = {}, &block)
38
+ create_table_without_auditing(table_name, options, &block)
39
+ unless options[:temporary] ||
40
+ PgAuditLog::IGNORED_TABLES.include?(table_name) ||
41
+ PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
42
+ PgAuditLog::Triggers.create_for_table(table_name)
43
+ end
44
+ end
45
+ alias_method_chain :create_table, :auditing
46
+
47
+ def rename_table_with_auditing(table_name, new_name)
48
+ rename_table_without_auditing(table_name, new_name)
49
+ if PgAuditLog::Triggers.tables_with_triggers.include?(table_name)
50
+ PgAuditLog::Triggers.drop_for_table(table_name)
51
+ end
52
+ unless PgAuditLog::IGNORED_TABLES.include?(table_name) ||
53
+ PgAuditLog::Triggers.tables_with_triggers.include?(new_name)
54
+ PgAuditLog::Triggers.create_for_table(new_name)
55
+ end
56
+ end
57
+ alias_method_chain :rename_table, :auditing
58
+
59
+ private
60
+
61
+ def user_id_and_name
62
+ current_user = Thread.current[:current_user]
63
+ user_id = current_user.try(:id) || "-1"
64
+ user_unique_name = current_user.try(:unique_name) || "UNKNOWN"
65
+ return [user_id, user_unique_name]
66
+ end
67
+
68
+ end
@@ -5,10 +5,6 @@ module PgAuditLog
5
5
  "audit_changes"
6
6
  end
7
7
 
8
- def custom_variable
9
- "audit"
10
- end
11
-
12
8
  def users_table_name
13
9
  "users"
14
10
  end
@@ -25,6 +21,30 @@ module PgAuditLog
25
21
  "last_accessed_at"
26
22
  end
27
23
 
24
+ def user_identifier_temporary_function(user_id)
25
+ sql = <<-SQL
26
+ CREATE OR REPLACE FUNCTION pg_temp.pg_audit_log_user_identifier() RETURNS integer
27
+ LANGUAGE plpgsql
28
+ AS $_$
29
+ BEGIN
30
+ RETURN #{user_id};
31
+ END
32
+ $_$;
33
+ SQL
34
+ end
35
+
36
+ def user_unique_name_temporary_function(username)
37
+ sql = <<-SQL
38
+ CREATE OR REPLACE FUNCTION pg_temp.pg_audit_log_user_unique_name() RETURNS varchar
39
+ LANGUAGE plpgsql
40
+ AS $_$
41
+ BEGIN
42
+ RETURN '#{username}';
43
+ END
44
+ $_$;
45
+ SQL
46
+ end
47
+
28
48
  def install
29
49
  execute <<-SQL
30
50
  CREATE OR REPLACE PROCEDURAL LANGUAGE plpgsql;
@@ -46,8 +66,8 @@ module PgAuditLog
46
66
  old_value := NULL;
47
67
  primary_key_column := NULL;
48
68
  primary_key_value := NULL;
49
- user_identifier := current_setting('#{custom_variable}.#{user_id_field}');
50
- unique_name := current_setting('#{custom_variable}.#{user_name_field}');
69
+ user_identifier := pg_temp.pg_audit_log_user_identifier();
70
+ unique_name := pg_temp.pg_audit_log_user_unique_name();
51
71
  column_name := col.column_name;
52
72
 
53
73
  EXECUTE 'SELECT pg_attribute.attname
@@ -1,3 +1,3 @@
1
1
  module PgAuditLog
2
- VERSION = "0.3.6"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -5,14 +5,8 @@ describe "the PostgreSQL database" do
5
5
  ActiveRecord::Base.connection.reconnect!
6
6
  end
7
7
 
8
- it "allows custom class variables for audit" do
9
- lambda {
10
- ActiveRecord::Base.connection.execute('SET audit.test = 1')
11
- }.should_not raise_error(ActiveRecord::StatementInvalid), "Your postgres is not configured for auditing. See README.rdoc"
12
- end
13
-
14
8
  it "has an audit log table" do
15
9
  ActiveRecord::Base.connection.table_exists?("audit_log").should be_true
16
10
  end
17
11
 
18
- end
12
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pg_audit_log
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-10-02 00:00:00.000000000Z
12
+ date: 2011-10-03 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &2160154260 !ruby/object:Gem::Requirement
16
+ requirement: &2152506680 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.0.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2160154260
24
+ version_requirements: *2152506680
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: pg
27
- requirement: &2160153480 !ruby/object:Gem::Requirement
27
+ requirement: &2152505720 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.0
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2160153480
35
+ version_requirements: *2152505720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rspec-rails
38
- requirement: &2160152760 !ruby/object:Gem::Requirement
38
+ requirement: &2152505120 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *2160152760
46
+ version_requirements: *2152505120
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: with_model
49
- requirement: &2160151720 !ruby/object:Gem::Requirement
49
+ requirement: &2152503960 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 0.1.3
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *2160151720
57
+ version_requirements: *2152503960
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: autotest
60
- requirement: &2160150700 !ruby/object:Gem::Requirement
60
+ requirement: &2152503100 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *2160150700
68
+ version_requirements: *2152503100
69
69
  description: A completely transparent audit logging component for your application
70
70
  using a stored procedure and triggers. Comes with specs for your project and a rake
71
71
  task to generate the reverse SQL to undo changes logged
@@ -94,6 +94,7 @@ files:
94
94
  - lib/pg_audit_log/entry.rb
95
95
  - lib/pg_audit_log/extensions/3.0/postgresql_adapter.rb
96
96
  - lib/pg_audit_log/extensions/3.1/postgresql_adapter.rb
97
+ - lib/pg_audit_log/extensions/shared/postgresql_adapter.rb
97
98
  - lib/pg_audit_log/function.rb
98
99
  - lib/pg_audit_log/triggers.rb
99
100
  - lib/pg_audit_log/version.rb
@@ -119,7 +120,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
119
120
  version: '0'
120
121
  segments:
121
122
  - 0
122
- hash: 2478681401597337909
123
+ hash: -732310515117041189
123
124
  required_rubygems_version: !ruby/object:Gem::Requirement
124
125
  none: false
125
126
  requirements:
@@ -128,7 +129,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
128
129
  version: '0'
129
130
  segments:
130
131
  - 0
131
- hash: 2478681401597337909
132
+ hash: -732310515117041189
132
133
  requirements: []
133
134
  rubyforge_project:
134
135
  rubygems_version: 1.8.10