Closed ehannes closed 2 years ago
@infoman I happened to see your thumbs up on this issue. Are you actively using this gem? :slightly_smiling_face:
Hmm, not sure if I'm missing something obvious here, but this 501 Not Implemented server error
response looks a bit weird, doesn't it? :thinking:
$ curl --head 'https://apps.fortnox.se/oauth-v1/auth?client_id=[FILTERD-ID]&response_type=code&state=somestate&scope=customer'
HTTP/2 501
content-type: text/plain;charset=UTF-8
date: Fri, 20 May 2022 21:55:51 GMT
x-uid: 08e50a0d
server: Fortnox
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: strict-origin-when-cross-origin
content-security-policy: upgrade-insecure-requests;frame-ancestors https://*.fortnox.se;report-uri /api/cspreport;connect-src 'self' https://a.storyblok.com wss://*.fortnox.se *.fortnox.se *.findity.com *.livechatinc.com mybusiness.pwc.se themes.googleusercontent.com s3.amazonaws.com/helpjuice-static/ *.helpjuice.com *.vimeo.com fonts.googleapis.com fonts.gstatic.com 'unsafe-inline' 'unsafe-eval' blob: data:
x-frame-options: sameorigin
strict-transport-security: max-age=31536000; includeSubdomains
Could it be that you are making a HEAD request? Btw, I have stopped using this gem on my latest applications since it's compatible with new versions of Ruby and Rails. So I had to implement this feature and did it naively so:
def api_client
Faraday.new('https://api.fortnox.se/3') do |conn|
conn.adapter :net_http
conn.request :authorization, 'Bearer', access_token.token
conn.request :json
conn.response :raise_error
conn.response :json, parser_options: { symbolize_names: true }
conn.response :logger, nil, { headers: true, bodies: true, log_level: :debug }
end
end
def redis
@redis ||= Redis.new
end
def access_token
return @access_token if defined? @access_token
@access_token = begin
oauth_client = OAuth2::Client.new(
ENV.fetch('FORTNOX_CLIENT_ID'),
ENV.fetch('FORTNOX_CLIENT_SECRET'),
{
site: 'https://apps.fortnox.se',
token_url: 'oauth-v1/token',
}
) do |conn|
conn.adapter :net_http
conn.request :url_encoded
conn.request :authorization,
:basic,
ENV.fetch('FORTNOX_CLIENT_ID'),
ENV.fetch('FORTNOX_CLIENT_SECRET')
end
cached_token_data = redis.get('fortnox_access_token_data')
token_data = cached_token_data ? Marshal.load(cached_token_data) : {}
access_token = OAuth2::AccessToken.new(
oauth_client,
token_data[:access_token] || ENV.fetch('FORTNOX_ACCESS_TOKEN'),
{
refresh_token: token_data[:refresh_token] || ENV.fetch('FORTNOX_REFRESH_TOKEN'),
expires_at: token_data[:expires_at] || 5.minutes.ago
}
)
if access_token.expired?
access_token = access_token.refresh!
redis.set('fortnox_access_token_data', Marshal.dump({
access_token: access_token.token,
refresh_token: access_token.refresh_token,
expires_at: access_token.expires_at
}))
end
access_token
end
end
Oh, nice @samuel02! I'll look into it.
We are working on better Ruby support in this gem. Would you be interesting in using this gem again if we fixed the support for newer Ruby versions? Which version are you using?
Yeah, probably! On this app I'm using Ruby 3.1.2
@samuel02 there's #212 to support Ruby 3. We hope that will be the next step for us after we have implemented support for OAuth 2.
Fortnox are changing to OAuth 2 for Authorization. You can read more about it in Authorizing your integration. The old way of authorize integrations will stop to work 9/1-2022.
Note that long lived access tokens used for this type of integration that fortnox-api is has a life span of 10 years. If you need new access tokens, or if your current tokens are deprecating, you will need to use OAuth 2.
access_token
andrefresh_token
access_token
andrefresh_token
Dotenv
Currently, environment variables are hard coded in
spec/support/helpers/configuration_helper.rb
since those values are included in plain text in the vcr cassettes anyway. But nowaccess_token
is short lived andclient_secret
will not be submitted at all in those requests. So maybe it would be suitable to move environment variables to Dotenv.Refresh tokens and vcr cassettes
We use vcr to record HTTP requests during testing. We should probably request an access token manually before creating new vcr cassettes. We might even need to request a new refresh token since we don't run the tests at regular basis. The refresh token is only valid for 31 days.