Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove Rack::Auth::Digest #2361

Merged
merged 12 commits into from
Oct 25, 2023
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
### 1.9.0 (Next)
### 2.0.0 (Next)
dblock marked this conversation as resolved.
Show resolved Hide resolved

#### Features

* [#2353](https://github.com/ruby-grape/grape/pull/2353): Added Rails 7.1 support - [@ericproulx](https://github.com/ericproulx).
* [#2355](https://github.com/ruby-grape/grape/pull/2355): Set response headers based on Rack version - [@schinery](https://github.com/schinery).
* [#2360](https://github.com/ruby-grape/grape/pull/2360): Reduce gem size by removing specs - [@ericproulx](https://github.com/ericproulx).
* [#2361](https://github.com/ruby-grape/grape/pull/2361): Remove rack::auth::digest - [@ninoseki](https://github.com/ninoseki).
dblock marked this conversation as resolved.
Show resolved Hide resolved
* Your contribution here.

#### Fixes
Expand Down
20 changes: 3 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
- [Active Model Serializers](#active-model-serializers)
- [Sending Raw or No Data](#sending-raw-or-no-data)
- [Authentication](#authentication)
- [Basic and Digest Auth](#basic-and-digest-auth)
- [Basic Auth](#basic-auth)
- [Register custom middleware for authentication](#register-custom-middleware-for-authentication)
- [Describing and Inspecting an API](#describing-and-inspecting-an-api)
- [Current Route and Endpoint](#current-route-and-endpoint)
Expand Down Expand Up @@ -3422,9 +3422,9 @@ end

## Authentication

### Basic and Digest Auth
### Basic Auth

Grape has built-in Basic and Digest authentication (the given `block`
Grape has built-in Basic authentication (the given `block`
is executed in the context of the current `Endpoint`). Authentication
applies to the current namespace and any children, but not parents.

Expand All @@ -3435,20 +3435,6 @@ http_basic do |username, password|
end
```

Digest auth supports clear-text passwords and password hashes.

```ruby
http_digest({ realm: 'Test Api', opaque: 'app secret' }) do |username|
# lookup the user's password here
end
```

```ruby
http_digest(realm: { realm: 'Test Api', opaque: 'app secret', passwords_hashed: true }) do |username|
# lookup the user's password hash here
end
```

### Register custom middleware for authentication

Grape can use custom Middleware for authentication. How to implement these
Expand Down
10 changes: 8 additions & 2 deletions UPGRADING.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Upgrading Grape
===============

### Upgrading to >= 1.9.0
### Upgrading to >= 2.0.0

#### Headers

As per [rack/rack#1592](https://github.com/rack/rack/issues/1592) Rack 3.0 is enforcing the HTTP/2 semantics, and thus treats all headers as lowercase. Starting with Grape 1.9.0, headers will be cased based on what version of Rack you are using.
As per [rack/rack#1592](https://github.com/rack/rack/issues/1592) Rack 3.0 is enforcing the HTTP/2 semantics, and thus treats all headers as lowercase. Starting with Grape 2.0.0, headers will be cased based on what version of Rack you are using.

Given this request:

Expand All @@ -30,6 +30,12 @@ end

See [#2355](https://github.com/ruby-grape/grape/pull/2355) for more information.

#### Digest auth deprecation

Digest auth has been removed along with the deprecation of `Rack::Auth::Digest` in Rack 3.

See [#2294](https://github.com/ruby-grape/grape/issues/2294) for more information.

### Upgrading to >= 1.7.0

#### Exceptions renaming
Expand Down
1 change: 0 additions & 1 deletion lib/grape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
require 'rack/builder'
require 'rack/accept'
require 'rack/auth/basic'
require 'rack/auth/digest/md5'
require 'set'
require 'bigdecimal'
require 'date'
Expand Down
3 changes: 1 addition & 2 deletions lib/grape/middleware/auth/strategies.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ def add(label, strategy, option_fetcher = ->(_) { [] })

def auth_strategies
@auth_strategies ||= {
http_basic: StrategyInfo.new(Rack::Auth::Basic, ->(settings) { [settings[:realm]] }),
http_digest: StrategyInfo.new(Rack::Auth::Digest::MD5, ->(settings) { [settings[:realm], settings[:opaque]] })
http_basic: StrategyInfo.new(Rack::Auth::Basic, ->(settings) { [settings[:realm]] })
}
end

Expand Down
88 changes: 0 additions & 88 deletions spec/grape/middleware/auth/strategies_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,92 +29,4 @@ def app
expect(last_response.status).to eq(401)
end
end

context 'Digest MD5 Auth' do
RSpec::Matchers.define :be_challenge do
match do |actual_response|
actual_response.status == 401 &&
actual_response['WWW-Authenticate'].start_with?('Digest ') &&
actual_response.body.empty?
end
end

module StrategiesSpec
class PasswordHashed < Grape::API
http_digest(realm: { realm: 'Test Api', opaque: 'secret', passwords_hashed: true }) do |username|
{ 'foo' => Digest::MD5.hexdigest(['foo', 'Test Api', 'bar'].join(':')) }[username]
end

get '/test' do
[{ hey: 'you' }, { there: 'bar' }, { foo: 'baz' }]
end
end

class PasswordIsNotHashed < Grape::API
http_digest(realm: 'Test Api', opaque: 'secret') do |username|
{ 'foo' => 'bar' }[username]
end

get '/test' do
[{ hey: 'you' }, { there: 'bar' }, { foo: 'baz' }]
end
end
end

context 'when password is hashed' do
def app
StrategiesSpec::PasswordHashed
end

it 'is a digest authentication challenge' do
get '/test'
expect(last_response).to be_challenge
end

it 'throws a 401 if no auth is given' do
get '/test'
expect(last_response.status).to eq(401)
end

it 'authenticates if given valid creds' do
digest_authorize 'foo', 'bar'
get '/test'
expect(last_response.status).to eq(200)
end

it 'throws a 401 if given invalid creds' do
digest_authorize 'bar', 'foo'
get '/test'
expect(last_response.status).to eq(401)
end
end

context 'when password is not hashed' do
def app
StrategiesSpec::PasswordIsNotHashed
end

it 'is a digest authentication challenge' do
get '/test'
expect(last_response).to be_challenge
end

it 'throws a 401 if no auth is given' do
get '/test'
expect(last_response.status).to eq(401)
end

it 'authenticates if given valid creds' do
digest_authorize 'foo', 'bar'
get '/test'
expect(last_response.status).to eq(200)
end

it 'throws a 401 if given invalid creds' do
digest_authorize 'bar', 'foo'
get '/test'
expect(last_response.status).to eq(401)
end
end
end
end