mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-01-27 21:06:49 +00:00
Merge pull request #11101 from mkllnk/dfc-api-key
Allow access to DFC API with OFN API token
This commit is contained in:
@@ -15,6 +15,12 @@ account with a trusted OIDC provider. Currently these are:
|
||||
But you can also authenticate with your OFN user login (session cookie) through
|
||||
your browser.
|
||||
|
||||
And you can also use your OFN API token in the HTTP header. For example:
|
||||
|
||||
```
|
||||
X-Api-Token: d6ccf8685b8cd29b67ae6186e9ceb423bd2ac30b7c880223
|
||||
```
|
||||
|
||||
## API endpoints
|
||||
|
||||
The API is under development and this list may be out of date.
|
||||
|
||||
@@ -19,7 +19,7 @@ class AuthorizationControl
|
||||
end
|
||||
|
||||
def user
|
||||
oidc_user || ofn_user
|
||||
oidc_user || ofn_api_user || ofn_user
|
||||
rescue JWT::ExpiredSignature
|
||||
nil
|
||||
end
|
||||
@@ -30,6 +30,10 @@ class AuthorizationControl
|
||||
find_ofn_user(decode_token) if access_token
|
||||
end
|
||||
|
||||
def ofn_api_user
|
||||
Spree::User.find_by(spree_api_key: ofn_api_token) if ofn_api_token.present?
|
||||
end
|
||||
|
||||
def ofn_user
|
||||
@request.env['warden']&.user
|
||||
end
|
||||
@@ -46,6 +50,10 @@ class AuthorizationControl
|
||||
@request.headers['Authorization'].to_s.split(' ').last
|
||||
end
|
||||
|
||||
def ofn_api_token
|
||||
@request.headers["X-Api-Token"]
|
||||
end
|
||||
|
||||
def find_ofn_user(payload)
|
||||
return if payload["email"].blank?
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ describe AuthorizationControl do
|
||||
create(:oidc_user) # another user
|
||||
token = allow_token_for(email: user.email)
|
||||
|
||||
expect(auth(token).user).to eq user
|
||||
expect(auth(oidc_token: token).user).to eq user
|
||||
end
|
||||
|
||||
it "ignores blank email" do
|
||||
@@ -20,28 +20,56 @@ describe AuthorizationControl do
|
||||
create(:user, uid: "")
|
||||
token = allow_token_for(email: nil)
|
||||
|
||||
expect(auth(token).user).to eq nil
|
||||
expect(auth(oidc_token: token).user).to eq nil
|
||||
end
|
||||
|
||||
it "ignores non-existent user" do
|
||||
user
|
||||
token = allow_token_for(email: generate(:random_email))
|
||||
|
||||
expect(auth(token).user).to eq nil
|
||||
expect(auth(oidc_token: token).user).to eq nil
|
||||
end
|
||||
|
||||
it "ignores expired signatures" do
|
||||
token = allow_token_for(exp: Time.now.to_i, email: user.email)
|
||||
|
||||
expect(auth(token).user).to eq nil
|
||||
expect(auth(oidc_token: token).user).to eq nil
|
||||
end
|
||||
end
|
||||
|
||||
def auth(token)
|
||||
describe "with OFN API token" do
|
||||
it "finds the user of the API key" do
|
||||
user.update!(spree_api_key: "1234")
|
||||
|
||||
expect(auth(api_token: "1234").user).to eq user
|
||||
end
|
||||
|
||||
it "returns nil if the token doesn't match" do
|
||||
user.update!(spree_api_key: "1234")
|
||||
|
||||
expect(auth(api_token: "123").user).to eq nil
|
||||
end
|
||||
|
||||
it "ignores a missing token" do
|
||||
user.update!(spree_api_key: nil)
|
||||
|
||||
expect(auth(api_token: nil).user).to eq nil
|
||||
end
|
||||
|
||||
it "ignores empty tokens" do
|
||||
user.update!(spree_api_key: "")
|
||||
|
||||
expect(auth(api_token: "").user).to eq nil
|
||||
end
|
||||
end
|
||||
|
||||
def auth(oidc_token: nil, api_token: nil)
|
||||
headers = {}
|
||||
headers["Authorization"] = "Bearer #{oidc_token}" if oidc_token
|
||||
headers["X-Api-Token"] = api_token if api_token
|
||||
|
||||
described_class.new(
|
||||
double(:request,
|
||||
headers: { "Authorization" => "Bearer #{token}" },
|
||||
env: { 'warden' => nil })
|
||||
double(:request, headers:, env: { 'warden' => nil })
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user