Skip to content

Commit

Permalink
controller_info and enabled_for_controller (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
devvit authored and jaredbeck committed Feb 22, 2018
1 parent 019b249 commit bc3644d
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 9 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ Breaking Changes

Added

- None
- Two functions inherit from rails
- info_for_paper_trail
- paper_trail_enabled_for_request

Fixed

Expand Down
19 changes: 15 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,23 @@ into the `create_versions` migration that was generated into your `db/migrate` d

5. Add `has_paper_trail` to the models you want to track.

PaperTrail provides a helper extension that acts similar to the controller mixin
PaperTrail provides some helper extensions that acts similar to the controller mixin
it provides for `Rails` applications.

It will set `PaperTrail.whodunnit` to whatever is returned by a method named
`user_for_paper_trail` which you can define inside your Sinatra Application. (by
default it attempts to invoke a method named `current_user`)
In your helpers you can override these methods:

```ruby
# Returns the user who is responsible for any changes that occur.
# Defaults to current_user.
user_for_paper_trail

# Returns any information about the controller or request that you want
# PaperTrail to store alongside any changes that occur.
info_for_paper_trail

# Returns `true` (default) or `false` to turn PaperTrail on/off for per request.
paper_trail_enabled_for_request
```

If you're using the modular [`Sinatra::Base`][4] style of application, you will
need to register the extension:
Expand Down
50 changes: 48 additions & 2 deletions lib/paper_trail/sinatra.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ module Sinatra
def self.registered(app)
app.use RequestStore::Middleware
app.helpers self
app.before { set_paper_trail_whodunnit }
app.before {
set_paper_trail_whodunnit
set_paper_trail_request_info
set_paper_trail_enabled_for_request
}
end

protected
Expand All @@ -27,13 +31,55 @@ def user_for_paper_trail
current_user
end

# Returns any information about the controller or request that you
# want PaperTrail to store alongside any changes that occur. By
# default this returns an empty hash.
#
# Override this method in your controller to return a hash of any
# information you need. The hash's keys must correspond to columns
# in your `versions` table, so don't forget to add any new columns
# you need.
#
# For example:
#
# {:ip => request.remote_ip, :user_agent => request.user_agent}
#
# The columns `ip` and `user_agent` must exist in your `versions` # table.
#
# Use the `:meta` option to
# `PaperTrail::Model::ClassMethods.has_paper_trail` to store any extra
# model-level data you need.
def info_for_paper_trail
{}
end

# Returns `true` (default) or `false` depending on whether PaperTrail
# should be active for the current request.
#
# Override this method in your controller to specify when PaperTrail
# should be off.
def paper_trail_enabled_for_request
::PaperTrail.enabled?
end

private

# Tells PaperTrail who is responsible for any changes that occur.
def set_paper_trail_whodunnit
@set_paper_trail_whodunnit_called = true
::PaperTrail.whodunnit = user_for_paper_trail if ::PaperTrail.enabled?
end

# Tells PaperTrail any information from the controller you want to store
# alongside any changes that occur.
def set_paper_trail_request_info
::PaperTrail.controller_info = info_for_paper_trail if ::PaperTrail.enabled?
end

# Tells PaperTrail whether versions should be saved in the current
# request.
def set_paper_trail_enabled_for_request
::PaperTrail.enabled_for_controller = paper_trail_enabled_for_request if ::PaperTrail.enabled?
end
end
end

Expand Down
4 changes: 3 additions & 1 deletion spec/create_db.sql
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ create table versions (
object varchar,
object_changes varchar,
transaction_id integer,
created_at datetime
created_at datetime,
ip varchar,
user_agent varchar
);

create table widgets (
Expand Down
36 changes: 35 additions & 1 deletion spec/modular_sinatra_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ class BaseApp < Sinatra::Base
def current_user
@current_user ||= OpenStruct.new(id: "foobar")
end

def info_for_paper_trail
{ ip: request.ip, user_agent: request.user_agent }
end

def paper_trail_enabled_for_request
request.user_agent.to_s =~ /^(?!edge)/
end
end

RSpec.describe "modular-style sinatra application" do
Expand All @@ -25,7 +33,10 @@ def app
end

it "baseline" do
expect(Widget.create.versions.first.whodunnit).to be_nil
widget = Widget.create.versions.first
expect(widget.whodunnit).to be_nil
expect(widget.ip).to be_nil
expect(widget.user_agent).to be_nil
end

context "`PaperTrail::Sinatra` in a `Sinatra::Base` application" do
Expand All @@ -38,5 +49,28 @@ def app
expect(widget.versions.size).to eq(1)
expect(widget.versions.first.whodunnit).to eq("foobar")
end

it "sets `info_for_paper_trail`" do
env "HTTP_USER_AGENT", "mozilla"
get "/test"
expect(last_response.body).to eq("Hello")
widget = Widget.last
expect(widget).to_not be_nil
expect(widget.name).to eq("foo")
expect(widget.versions.size).to eq(1)
expect(widget.versions.first.whodunnit).to eq("foobar")
expect(widget.versions.first.ip).to eq("127.0.0.1")
expect(widget.versions.first.user_agent).to eq("mozilla")
end

it "sets `paper_trail_enabled_for_request`" do
env "HTTP_USER_AGENT", "edge"
get "/test"
expect(last_response.body).to eq("Hello")
widget = Widget.last
expect(widget).to_not be_nil
expect(widget.name).to eq("foo")
expect(widget.versions.size).to eq(0)
end
end
end
32 changes: 32 additions & 0 deletions spec/sinatra_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ class Application
def current_user
@current_user ||= OpenStruct.new(id: "raboof")
end

def info_for_paper_trail
{ ip: request.ip, user_agent: request.user_agent }
end

def paper_trail_enabled_for_request
request.user_agent.to_s =~ /^(?!webkit)/
end
end
end

Expand All @@ -35,5 +43,29 @@ def app
expect(widget.versions.size).to eq(1)
expect(widget.versions.first.whodunnit).to eq("raboof")
end

it "sets `info_for_paper_trail`" do
env "HTTP_USER_AGENT", "chrome"
env "HTTP_X_FORWARDED_FOR", "8.8.8.8"
get "/test"
expect(last_response.body).to eq("Hai")
widget = Widget.last
expect(widget).to_not be_nil
expect(widget.name).to eq("bar")
expect(widget.versions.size).to eq(1)
expect(widget.versions.first.whodunnit).to eq("raboof")
expect(widget.versions.first.ip).to eq("8.8.8.8")
expect(widget.versions.first.user_agent).to eq("chrome")
end

it "sets `paper_trail_enabled_for_request`" do
env "HTTP_USER_AGENT", "webkit"
get "/test"
expect(last_response.body).to eq("Hai")
widget = Widget.last
expect(widget).to_not be_nil
expect(widget.name).to eq("bar")
expect(widget.versions.size).to eq(0)
end
end
end

0 comments on commit bc3644d

Please sign in to comment.