Skip to content

Commit

Permalink
Merge pull request #39 from square/tarcieri/idempotent-credentials
Browse files Browse the repository at this point in the history
Make credentials idempotent
  • Loading branch information
tarcieri committed Jul 20, 2016
2 parents 531f838 + 7c8c359 commit 3280815
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 4 deletions.
7 changes: 6 additions & 1 deletion lib/rails/auth/credentials.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Credentials
extend Forwardable
include Enumerable

def_delegators :@credentials, :[], :fetch, :empty?, :key?, :each, :to_hash
def_delegators :@credentials, :fetch, :empty?, :key?, :each, :to_hash

def self.from_rack_env(env)
new(env.fetch(Rails::Auth::Env::CREDENTIALS_ENV_KEY, {}))
Expand All @@ -22,10 +22,15 @@ def initialize(credentials = {})
end

def []=(type, value)
return if @credentials.key?(type) && @credentials[type] == value
raise TypeError, "expected String for type, got #{type.class}" unless type.is_a?(String)
raise AlreadyAuthorizedError, "credential '#{type}' has already been set" if @credentials.key?(type)
@credentials[type] = value
end

def [](type)
@credentials[type.to_s]
end
end
end
end
25 changes: 22 additions & 3 deletions spec/rails/auth/credentials_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,29 @@
end
end

describe "[]=" do
it "raises AlreadyAuthorizedError if credential has already been set" do
context "when called twice for the same credential type" do
let(:example_credential) { double(:credential1) }
let(:second_credential) { double(:credential2) }

let(:example_env) { Rack::MockRequest.env_for("https://www.example.com") }

it "succeeds if the credentials are the same" do
allow(example_credential).to receive(:==).and_return(true)

Rails::Auth.add_credential(example_env, example_credential_type, example_credential)

expect do
Rails::Auth.add_credential(example_env, example_credential_type, second_credential)
end.to_not raise_error
end

it "raises Rails::Auth::AlreadyAuthorizedError if the credentials are different" do
allow(example_credential).to receive(:==).and_return(false)

Rails::Auth.add_credential(example_env, example_credential_type, example_credential)

expect do
credentials[example_credential_type] = example_credential_value
Rails::Auth.add_credential(example_env, example_credential_type, second_credential)
end.to raise_error(Rails::Auth::AlreadyAuthorizedError)
end
end
Expand Down

0 comments on commit 3280815

Please sign in to comment.